Bookmarking things: xml_loc and xml_getloc

Previous: xml_replace and xml_replacecontent: Replacing an element with another. ] [ Top: index ] [ Next: Working with attributes: xml_set and xml_attrval ]

 
XML * xml_loc (XML * start, const char * loc)
{
   char * mark;
   const char * attrval;
   char piece[64];
   int i;
   int count;

   if (!loc) return (start);
   if (!*loc) return (start);

   while (start && start->name == NULL) start = xml_next (start);
   if (!start) return (NULL);

   while (*loc == ' ') loc++;
   i = 0;
   while (*loc && *loc != '.') piece[i++] = *loc++;
   piece[i] = '\0';
   if (*loc) loc++;
   while (*loc == ' ') loc++;

   mark = strchr (piece, ']');
   if (mark) *mark = '\0';
   mark = strchr (piece, '(');
   if (mark) {
      *mark++ = '\0';
      count = atoi (mark);
      mark = NULL;
   } else {
      count = 0;
      mark = strchr (piece, '[');
      if (mark) {
         *mark++ = '\0';
      }
   }

   while (start) {
      if (start->name == NULL) {
         start = xml_next (start);
         continue;
      }
      if (strcmp (start->name, piece)) {
         start = xml_next (start);
         continue;
      }
      if (count) {
         count --;
         start = xml_next (start);
         continue;
      }
      if (!mark) {
         if (*loc) return (xml_loc (xml_first (start), loc));
         return (start);
      }
      attrval = xml_attrval(start, "id");
      if (attrval) {
         if (strcmp (attrval, mark)) {
            start = xml_next (start);
            continue;
         }
         if (*loc) return (xml_loc (xml_first(start), loc));
         return (start);
      }
      attrval = xml_attrval(start, "name");
      if (attrval) {
         if (strcmp (attrval, mark)) {
            start = xml_next (start);
            continue;
         }
         if (*loc) return (xml_loc (xml_first(start), loc));
         return (start);
      }
   }
   return (NULL);
}
Building our locator is recursive. We build our parent's locator, append a dot, and qualify it.
 
void xml_getloc (XML * xml, char *loc, int len)
{
   int s;
   int count;
   XML * sib;
   if (xml->parent != NULL) {
      xml_getloc (xml->parent, loc, len);
   } else {
      *loc = '\0';
   }
   s = strlen (loc);
   if (s > 0 && s < len-1) { strcat (loc, "."); s++; }
   len -= s;
   loc += s;
   if (strlen(xml->name) < len) {
      strcpy (loc, xml->name);
   } else {
      strncpy (loc, xml->name, len-1);
      loc[len-1] = '\0';
   }
   if (xml->parent == NULL) return;
   sib = xml_first(xml->parent);
   count = 0;
   while (sib != xml && sib != NULL) {
      if (sib->name != NULL) {
         if (!strcmp (sib->name, xml->name)) count ++;
      }
      sib = xml_next(sib);
   }
   if (count > 0 && s > 4) {
      strcat (loc, "(");
      sprintf (loc + strlen(loc), "%d", count);
      strcat (loc, ")");
   }
}
Previous: xml_replace and xml_replacecontent: Replacing an element with another. ] [ Top: index ] [ Next: Working with attributes: xml_set and xml_attrval ]


This code and documentation are released under the terms of the GNU license. They are additionally copyright (c) 2000, Vivtek. All rights reserved except those explicitly granted under the terms of the GNU license. This presentation was created using LPML.