3

I could not find much examples of evaluate XPath using xerces-c 3.1.

Given the following sample XML input:

<abc> 
    <def>AAA BBB CCC</def>
</abc>

I need to retrieve the "AAA BBB CCC" string by the XPath "/abc/def/text()[0]".

The following code works:

XMLPlatformUtils::Initialize();
// create the DOM parser
XercesDOMParser *parser = new XercesDOMParser;
parser->setValidationScheme(XercesDOMParser::Val_Never);
parser->parse("test.xml");
// get the DOM representation
DOMDocument *doc = parser->getDocument();
// get the root element
DOMElement* root = doc->getDocumentElement();

// evaluate the xpath
DOMXPathResult* result=doc->evaluate(
    XMLString::transcode("/abc/def"), // "/abc/def/text()[0]"
    root,
    NULL,
    DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, //DOMXPathResult::ANY_UNORDERED_NODE_TYPE, //DOMXPathResult::STRING_TYPE,
    NULL);

// look into the xpart evaluate result
result->snapshotItem(0);
std::cout<<StrX(result->getNodeValue()->getFirstChild()->getNodeValue())<<std::endl;;

XMLPlatformUtils::Terminate();
return 0;

But I really hate that:

result->getNodeValue()->getFirstChild()->getNodeValue()

Has it to be a node set instead of the exact node I want?

I tried other format of XPath such as "/abc/def/text()[0]", and "DOMXPathResult::STRING_TYPE". xerces always thrown exception.

What did I do wrong?

ulidtko
  • 14,740
  • 10
  • 56
  • 88
John Crane
  • 371
  • 5
  • 14

1 Answers1

4

I don't code with Xerces C++ but it seems to implement the W3C DOM Level 3 so based on that I would suggest to select an element node with a path like /abc/def and then simply to access result->getNodeValue()->getTextContent() to get the contents of the element (e.g. AAA BBB CCC).

As far as I understand the DOM APIs, if you want a string value then you need to use a path like string(/abc/def) and then result->getStringValue() should do (if the evaluate method requests any type or STRING_TYPE as the result type).

Other approaches if you know you are only interested in the first node in document order you could evaluate /abc/def with FIRST_ORDERED_NODE_TYPE and then access result->getNodeValue()->getTextContent().

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • 1
    result->getStringValue() always throw, no matter what TYPE is passed into the evaluate(). result->getNodeValue()->getTextContent() works. Thanks – John Crane Jan 07 '13 at 18:39
  • It will be great to have an XPath to make the result->getStringValue() work. Anybody knows how? – John Crane Jan 07 '13 at 18:42
  • @JohnCrane Is there a way to know if a document is owned by a parser?. Can you please have a look at this question.. http://stackoverflow.com/questions/23673300/how-to-know-if-a-domdocument-is-created-using-a-parser – Pavan Dittakavi May 15 '14 at 10:13
  • Xerces does not support string return type xpaths: https://github.com/apache/xerces-c/blob/4bac3c53e44506591c2892cc19f0452be169b401/src/xercesc/dom/impl/DOMXPathExpressionImpl.cpp#L119 – Chronial Aug 10 '22 at 20:36