I'm curently porting a C++ project from libxml2 to pugixml. I have an XPath query that used to work perfectly well with libxml2 but returns zero nodes with pugixml:
"//*[local-name(.) = '" + name + "']"
where name
is the name of the elements I want to retrieve. Can anyone shed any light on what's happening?
Code:
const string path = "//*[local-name(.) = '" + name + "']";
std::cerr << path << std::endl;
try {
const xpath_node_set nodes = this->doc.select_nodes(path.c_str());
return nodes;
} catch(const xpath_exception& e) {
std::cerr << e.what() << std::endl;
throw logic_error("Could not select elements from document.");
}
Name: "Page"
XML:
<MyDocument>
<Pages>
<Page>
<Para>
<Word>Some</Word>
<Word>People</Word>
</Para>
</Page>
<Page>
<Para>
<Word>Some</Word>
<Word>Other</Word>
<Word>People</Word>
</Para>
</Page>
</Pages>
</MyDocument>
This program works for me. Are you using the latest version of pugixml?
Alternatively I did notice that pugixml isn't good with namespaces, you may need to specify them in the node name you are searching for.
I just checked and it works fine with namespaces.
#include <pugixml.hpp>
#include <iostream>
const char* xml =
"<MyDocument>"
" <Pages>"
" <Page>"
" <Para>"
" <Word>Some</Word>"
" <Word>People</Word>"
" </Para>"
" </Page>"
" <Page>"
" <Para>"
" <Word>Some</Word>"
" <Word>Other</Word>"
" <Word>People</Word>"
" </Para>"
" </Page>"
" </Pages>"
"</MyDocument>";
int main()
{
std::string name = "Para";
const std::string path = "//*[local-name(.) = '" + name + "']";
pugi::xml_parse_result result;
pugi::xml_document doc;
doc.load(xml);
const pugi::xpath_node_set nodes = doc.select_nodes(path.c_str());
for(auto& node: nodes)
{
std::cout << node.node().name() << '\n';
}
}
OUTPUT
Para
Para