[英]How to use XPath in XMLReader API of libxml2?
这里的教程说,如果我们扩展当前节点并将其设置为xmlXPathContext
对象的上下文节点,则可以在XMLReader API中使用XPath。 不幸的是,本教程提供的示例是使用Python编写的,我完全不懂这种语言。 我试图在C ++中创建自己的示例,但遇到了麻烦。 问题是函数xmlXPathSetContextNode
总是失败。 下面是示例应用程序将读取的我的代码和XML文档。
// BUILD: g++ thisFile.cpp -std=c++11 -Wall $(xml2-config --cflags --libs)
#include <cstdio> // for function fopen, fseek, rewind, fread and fclose
#include <libxml/xmlreader.h> // for data type xmlTextReader
#include <libxml/xpath.h> // for data type xmlXPathContext
#include <memory> // for class template shared_ptr
#include <stdexcept> // for class runtime_error;
#define _X(s) ((const xmlChar *)s)
int main(int argc, char *argv[])
{
using std::shared_ptr;
// Create a text reader.
shared_ptr<xmlTextReader> reader(::xmlReaderForFile("sample.xml", NULL, 0), &::xmlFreeTextReader);
// Create a XPath context.
xmlDocPtr doc = ::xmlTextReaderCurrentDoc(reader.get());
shared_ptr<xmlXPathContext> ctxt(::xmlXPathNewContext(doc), &::xmlXPathFreeContext);
// Use the text reader to read the stream.
int ret;
try {
while ((ret = ::xmlTextReaderRead(reader.get())) == 1) {
// Ignore all nodes except <storyinfo>.
#if 0
xmlNodePtr node = ::xmlTextReaderCurrentNode(reader.get());
#else
xmlNodePtr node = ::xmlTextReaderExpand(reader.get());
#endif
if (::xmlStrncmp(node->name, _X("storyinfo"), 10) != 0) continue;
// Set the current node as the context node.
::printf("node: 0x%08X\n", (size_t)node);
if (::xmlXPathSetContextNode(node, ctxt.get()) == -1) {
::fprintf(stderr, "ERROR(%d): %s\n", ctxt->lastError.code, ctxt->lastError.message);
throw std::runtime_error("err_xpath_set_context");
}
// Use a XPath to find <datewritten>.
shared_ptr<xmlXPathObject> xpathFound(::xmlXPathEvalExpression(_X("datewritten"), ctxt.get()), &::xmlXPathFreeObject);
if (xmlXPathNodeSetGetLength(xpathFound->nodesetval) == 0) throw std::runtime_error("err_xpath_not_fonud");
shared_ptr<xmlChar> zTextContent(::xmlXPathCastToString(xpathFound.get()), ::xmlFree);
::printf("found: %s\n", zTextContent.get());
break;
}
if (ret == -1) {
::fprintf(stderr, "ERROR: %s\n", "xmlTextReaderRead failure!");
return 1;
}
}
catch (const std::runtime_error& e) {
::fprintf(stderr, "ERROR: %s\n", e.what());
}
// Exit the program.
return 0;
}
XML文档的内容是
<?xml version="1.0"?>
<story>
<storyinfo>
<author>John Fleck</author>
<datewritten>June 2, 2002</datewritten>
<keyword>example keyword</keyword>
</storyinfo>
<body>
<headline>This is the headline</headline>
<para>This is the body text.</para>
</body>
</story>
任何提示将不胜感激。 提前致谢。 m(_ _)m
问题解决了。 功能xmlTextReaderCurrentDoc
不得任何之前调用xmlTextReaderRead
。 我将检查xmlTextReaderCurrentDoc
的返回值。 在上面的错误代码中,它返回NULL
。 因此,无法获得有效的XPath上下文。 官方文档没有提到何时才是调用xmlTextReaderCurrentDoc
的正确时间,因此我将在这里为其他遇到相同问题的人提供此xmlTextReaderCurrentDoc
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.