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.