I have an XML document that looks like this:
<RootNode schemeIdUri="xxx">
<cenc:pssh>some_data</cenc:pssh>
<bar:detail>details</bar:detail>
</RootNode>
And there's C++ code here that looks for the detail
node like this:
xmlNode *child;
for (child = xmlDocGetRootElement(doc)->children; child; child = child->next)
{
if (!strcmp((char*)child->name, "bar:detail"))
{
auto content = xmlNodeGetContent(child);
this->detail = (char*) content;
free(content);
}
}
This works with the XML above. But in one case, I instead got XML data that looks like this:
<RootNode xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:bar="urn:extra:details:2020" schemeIdUri="xxx">
<cenc:pssh>some_data</cenc:pssh>
<bar:detail>details</bar:detail>
</RootNode>
So, namespaces got added.
The C++ code above then fails, because the child names no longer contain the fully qualified name - they only contain the local part, which in this case is "detail".
Is this intentional? Is it mandatory to strip the bar:
prefix in this case? If so, what is then the correct / proper way to look for the details
child node with libxml2 in C++?
When working with XML namespaces, you have to check the local name and the namespace URI:
strcmp((char *) child->name, "detail") == 0 &&
child->ns != NULL &&
strcmp((char *) child->ns->href, "urn:extra:details:2020") == 0
Note the first document without namespace declarations is not namespace-well-formed. Also never use the namespace prefix to compare namespaces.