Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • L libxml2
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 90
    • Issues 90
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 7
    • Merge requests 7
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Container Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • GNOMEGNOME
  • libxml2
  • Issues
  • #7
Closed
Open
Issue created Jun 23, 2018 by Felix Bünemann@felixbuenemann

xmlTextReaderNextSibling() only works with preparsed documents

The current implementation for xmlTextReaderNextSibling(reader) is incomplete, since it only works for readers that have not been created from a preparsed document using xmlReaderWalker(doc).

This problem has been previously reported in Bugzilla Bug 793740 but there was no response from the maintainers.

Here's a testcase:

test.xml:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <child id="1">
    <subchild id="1.1"/>
    <subchild id="1.2"/>
    <subchild id="1.3"/>
  </child>
  <child id="2">
    <subchild id="2.1"/>
    <subchild id="2.2"/>
  </child>
</root>

test.c:

#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xmlreader.h>

static void processNode(xmlTextReaderPtr reader) {
  int type;
  xmlChar *id = NULL;

  type = xmlTextReaderNodeType(reader);
  if (type == XML_ELEMENT_NODE) {
    int depth;
    depth = xmlTextReaderDepth(reader);
    while (depth--) {
      printf("  ");
    }
    id = xmlTextReaderGetAttribute(reader, (xmlChar *)"id");
    if (id != NULL)
      printf("<%s id=\"%s\">\n", xmlTextReaderConstLocalName(reader), id);
    else
      printf("<%s>\n", xmlTextReaderConstLocalName(reader));
  }
}

static void check(xmlTextReaderPtr reader) {
  int depth;
  while (xmlTextReaderRead(reader) == 1) {
    depth = xmlTextReaderDepth(reader);
    /* processNode(reader); */
    if (depth == 2) break;
  }
  while (xmlTextReaderNextSibling(reader) == 1) {
    depth = xmlTextReaderDepth(reader);
    processNode(reader);
  }
}

int main(void) {
  const char filename[] = "test.xml";
  xmlTextReaderPtr reader = NULL;
  xmlDocPtr doc = NULL;
  int ret;

  doc = xmlReadFile(filename, NULL, 0);
  if (doc == NULL) {
    fprintf(stderr, "Unable to open %s\n", filename);
    return 1;
  }

  printf("doc reader\n");
  reader = xmlReaderWalker(doc);
  check(reader);
  xmlFreeTextReader(reader);
  reader = NULL;

  printf("file reader\n");
  reader = xmlNewTextReaderFilename(filename);
  if (reader != NULL) {
    check(reader);
    xmlFreeTextReader(reader);
  } else {
    fprintf(stderr, "Unable to open %s\n", filename);
  }
}

The code advances the reader into the node <child id="1"/> and then calls xmlTextReaderNextSibling(reader) to list the subchildren under that node.

Output:

doc reader
    <subchild id="1.1">
    <subchild id="1.2">
    <subchild id="1.3">
file reader

As can be seen from the output the code is not working for the file reader.

Looking at the implementation for xmlTextReaderNextSibling(reader) show the following comment:

Currently implemented only for Readers built on a document

So it looks like this feature was never fully implemented.

I have previously opened GNOME/libxml2#13 on GitHub to get this fixed and also attached the changes as a patch to the before mentioned Bugzilla issue, but it got no feedback.

I'll create a new Merge Request here on the GNOME GitLab to get it fixed.

Assignee
Assign to
Time tracking