12

I am supporting a legacy C++ application which uses Xerces-C for XML parsing. I've been spoiled by .Net and am used to using XPath to select nodes from a DOM tree.

Is there any way to get access some limited XPath functionality in Xerces-C? I'm looking for something like selectNodes("/for/bar/baz"). I could do this manually, but XPath is so nice by comparison.

Shog9
  • 156,901
  • 35
  • 231
  • 235
Adam Tegen
  • 25,378
  • 33
  • 125
  • 153

3 Answers3

7

See the xerces faq.

http://xerces.apache.org/xerces-c/faq-other-2.html#faq-9

Does Xerces-C++ support XPath? No.Xerces-C++ 2.8.0 and Xerces-C++ 3.0.1 only have partial XPath implementation for the purposes of handling Schema identity constraints. For full XPath support, you can refer Apache Xalan C++ or other Open Source Projects like Pathan.

It's fairly easy to do what you want using xalan however.

Brian Matthews
  • 8,506
  • 7
  • 46
  • 68
hookenz
  • 36,432
  • 45
  • 177
  • 286
6

Here is a working example of XPath evaluation with Xerces 3.1.2.

Sample XML

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
    <ApplicationSettings>hello world</ApplicationSettings>
</root>

C++

#include <iostream>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/util/TransService.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>

using namespace xercesc;
using namespace std;

int main()
{
  XMLPlatformUtils::Initialize();
  // create the DOM parser
  XercesDOMParser *parser = new XercesDOMParser;
  parser->setValidationScheme(XercesDOMParser::Val_Never);
  parser->parse("sample.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("/root/ApplicationSettings"),
      root,
      NULL,
      DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE,
      NULL);

  if (result->getNodeValue() == NULL)
  {
    cout << "There is no result for the provided XPath " << endl;
  }
  else
  {
    cout<<TranscodeToStr(result->getNodeValue()->getFirstChild()->getNodeValue(),"ascii").str()<<endl;
  }

  XMLPlatformUtils::Terminate();
  return 0;
}

Compile and run (assumes standard xerces library installation and C++ file named xpath.cpp)

g++ -g -Wall -pedantic -L/opt/lib -I/opt/include -DMAIN_TEST xpath.cpp -o xpath -lxerces-c
./xpath

Result

hello world
Mike S
  • 11,329
  • 6
  • 41
  • 76
  • Try changing the query to something like: count(//somenode/subnode/[@someattribute='somevalue']) and it throws an DOMXPathException – pfa May 06 '21 at 15:39
2

According to the FAQ, Xerces-C supports partial XPath 1 implementation:

The same engine is made available through the DOMDocument::evaluate API to let the user perform simple XPath queries involving DOMElement nodes only, with no predicate testing and allowing the "//" operator only as the initial step.

You use DOMDocument::evaluate() to evaluate the expression, which then returns a DOMXPathResult.

Jeff L
  • 6,108
  • 3
  • 23
  • 29
  • Has anyone used this functionality? Has it worked? If so, for what versions of Xerces-C? – Adam Tegen Jul 09 '09 at 20:35
  • @AdamTegen Yes, I know it's 6 years later but Xerces is still popular. I provided an example of how to accomplish XPath evaluation with Xerces 3.1.2. – Mike S Oct 14 '15 at 18:25