基本的XQilla XPath示例

时间:2013-02-22 17:14:35

标签: c++ xml xpath xqilla

我正在寻找一个基本的例子,说明如何设置XQilla以在包含XML的std :: string上使用XPath查询。 XQilla网站上的example 似乎在文件或URL上使用XQuery。

1 个答案:

答案 0 :(得分:5)

这是一个古老的问题,但我找到了答案,并且无法找到自己的答案。现在我解决了它,并认为我应该共享代码。

- 编辑 ,以下代码需要的许可证是在MIT和BSD下分享的,或者是什么......

XPathExtracter.h

#ifndef JOPPLI_XPATHEXTRACTER_H
#define JOPPLI_XPATHEXTRACTER_H

#include <string>
#include <vector>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/dom/DOM.hpp>

namespace Joppli
{
  using namespace xercesc;

  class XPathExtracter
  {
    public:
      typedef std::vector<std::string> Result;

      XPathExtracter();
     ~XPathExtracter();

      DOMDocument * getDocument(const std::string & xml);

      void extract(const std::string & query, DOMDocument * document,
                   Result * result);

  protected:
    DOMLSParser * parser;
    DOMImplementation * xqillaImplementation;

    private:
      static int count;
  };
}

#endif

XPathExtracter.cpp

#include "XPathExtracter.h"
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xqilla/xqilla-dom3.hpp>

namespace Joppli
{
  XPathExtracter::XPathExtracter()
  {
    // Initialise Xerces-C and XQilla using XQillaPlatformUtils
    if(count++ == 0)
      XQillaPlatformUtils::initialize();

    // Get the XQilla DOMImplementation object
    this->xqillaImplementation =
            DOMImplementationRegistry::getDOMImplementation(X("XPath2 3.0"));

    this->parser = this->xqillaImplementation->createLSParser(
      DOMImplementationLS::MODE_SYNCHRONOUS, 0);
  }

  XPathExtracter::~XPathExtracter()
  {
    this->parser->release();

    if(--count == 0)
      XQillaPlatformUtils::terminate();
  }

  DOMDocument * XPathExtracter::getDocument(const std::string & xml)
  {
    /* 
    // An alternative to simply setting the string input, as shown below

    MemBufInputSource * memBuf = new MemBufInputSource(
      (const XMLByte *) xml.c_str(),
      xml.size(),
      "xml (in memory)");

    DOMLSInput * input = this->xqillaImplementation->createLSInput();
    input->setByteStream(memBuf);

    DOMDocument * document = parser->parse(input);

    input->release();
    delete memBuf;

    return document;
    */

    DOMLSInput * input = this->xqillaImplementation->createLSInput();
    XMLCh * stringData = XMLString::transcode(xml.c_str());
    input->setStringData(stringData);
    DOMDocument * document = parser->parse(input);

    input->release();
    delete stringData;

    return document;
  }

  void XPathExtracter::extract(const std::string & query,
                               DOMDocument * document, Result * result)
  {
    // Parse an XPath 2 expression
    AutoRelease<DOMXPathExpression> expression(
      document->createExpression(X(query.c_str()), 0));

    // Execute the query
    AutoRelease<DOMXPathResult> xQillaResult(
      expression->evaluate(
        document,
        DOMXPathResult::ITERATOR_RESULT_TYPE, 0));

    // Iterate over the results
    while(xQillaResult->iterateNext())
    {
      char * content = XMLString::transcode(
        xQillaResult->getStringValue());

      result->push_back(content);

      delete content;
    }
  }

  int XPathExtracter::count = 0;
}

的main.cpp

#include <iostream>
#include "XPathExtracter.h"

int main(void)
{
  std::string * body = new std::string;

  // ... (logic to fill the body string with an xml/html value)

  // Extract
  using namespace xercesc;

  Joppli::XPathExtracter * driver = new Joppli::XPathExtracter();
  Joppli::XPathExtracter::Result * results = new Joppli::XPathExtracter::Result;
  DOMDocument * document = driver->getDocument(*body);
  driver->extract("html/head//title", document, results);
  driver->extract("html/head//meta//@name", document, results);
  driver->extract("html//body//a[@id=\"link_mx_es\"]", document, results);

  for(const auto & result : *results)
    std::cout << result << std::endl;

  delete results;
  delete driver;
  delete body;

  return 0;
}

我通过valgrind运行此代码并且它没有显示任何泄漏。