Я ищу базовый пример того, как настроить XQilla для использования запроса XPath к std :: string, содержащей XML. пример на сайте XQilla появляется возможность использовать XQuery либо для файла, либо для URL.
Это старый вопрос, но я искал ответ на этот вопрос и не мог найти его сам. Теперь я решил и решил поделиться кодом.
—редактировать, Лицензия, если это необходимо для приведенного ниже кода, распространяется под MIT и BSD или что-либо еще …
#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
#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;
}
#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, и он не показывает никаких утечек.
Других решений пока нет …