我决定在我的qt应用程序中使用libxml2
解析器,并且卡在xpath
表达式上。我找到了一个示例类和方法,并根据需要对其进行了一些修改。代码
QStringList* LibXml2Reader::XPathParsing(QXmlInputSource input)
{
xmlInitParser();
xmlDocPtr doc;
xmlXPathContextPtr xpathCtx;
xmlXPathObjectPtr xpathObj;
QStringList *valList =NULL;
QByteArray arr = input.data().toUtf8(); //convert input data to utf8
int length = arr.length();
const char* data = arr.data();
doc = xmlRecoverMemory(data,length); // build a tree, ignoring the errors
if(doc == NULL) { return NULL;}
xpathCtx = xmlXPathNewContext(doc);
if(xpathCtx == NULL)
{
xmlFreeDoc(doc);
xmlCleanupParser();
return NULL;
}
xpathObj = xmlXPathEvalExpression(BAD_CAST "//[@class='b-domik__nojs']", xpathCtx); //heres the parsing fails
if(xpathObj == NULL)
{
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
xmlCleanupParser();
return NULL;
}
xmlNodeSetPtr nodes = xpathObj->nodesetval;
int size = (nodes) ? nodes->nodeNr : 0;
if(size==0)
{
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
xmlCleanupParser();
return NULL;
}
valList = new QStringList();
for (int i = 0; i < size; i++)
{
xmlNodePtr current = nodes->nodeTab[i];
const char* str = (const char*)current->content;
qDebug() << "name: " << QString::fromLocal8Bit((const char*)current->name);
qDebug() << "content: " << QString::fromLocal8Bit((const char*)current->content) << "\r\n";
valList->append(QString::fromLocal8Bit(str));
}
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
xmlCleanupParser();
return valList;
}
例如,我向http://yandex.ru/发出请求,并尝试获取类
b-domik__nojs
的节点,该节点基本上是一个div。xpathObj = xmlXPathEvalExpression(BAD_CAST "//[@class='b-domik__nojs']", xpathCtx); //heres the parsing fails
问题是表达式
//[@class='b-domik__nojs']
根本不起作用。我在firefox xpath
ext。和Opera开发人员工具xpath
ext中进行了检查。在这里,这种表达非常完美。我也尝试获取具有属性的其他节点,但由于某种原因,ANY属性的
xpath
失败。我的方法有问题吗?另外,当我使用xmlRecover
加载树时,它在调试输出中给了我很多解析器错误。好的,我进一步使用了
libxml2
函数,并使用"//*"
表达式来获取文档中的所有元素,但是!它仅向我返回body标签的第一个子节点中的元素。 This is the yandex.ru dom tree因此基本上,它会获取第一个div
"div class="b-line b-line_bar"
中的所有元素,但由于某种原因不会在<body>
的其他子节点中查找其他元素。为什么会发生这种情况?也许
xmlParseMemory
由于某种原因没有建立完整的树?有没有可能解决此问题的解决方案。 最佳答案
好吧,如果我的错误是使用xml函数将html文档变成一棵树,那么它现在可以工作了。我使用了htmlReadMemory并且树已完全构建。再次输入一些代码
xmlInitParser();
xmlDocPtr doc;
xmlXPathContextPtr xpathCtx;
xmlXPathObjectPtr xpathObj;
QByteArray arr = input.data().toUtf8();
int length = arr.length();
const char* data = arr.data();
doc = htmlReadMemory(data,length,"",NULL,HTML_PARSE_RECOVER);
if(doc == NULL) { return NULL;}
xpathCtx = xmlXPathNewContext(doc);
if(xpathCtx == NULL)
{
xmlFreeDoc(doc);
xmlCleanupParser();
return NULL;
}
xpathObj = xmlXPathEvalExpression(BAD_CAST "//*[@class='b-domik__nojs']", xpathCtx);
等等
关于c++ - libxml2 xpath解析,无法按预期工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18128381/