libxml2 XPath解析,无法按预期工作
libxml2 xpath parsing, doesn't work as expected
我决定在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) << "rn";
valList->append(QString::fromLocal8Bit(str));
}
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
xmlFreeDoc(doc);
xmlCleanupParser();
return valList;
}
例如,我请求http://yandex.ru/并尝试获得类为CCD_ 3的节点,该节点基本上是一个div.
xpathObj = xmlXPathEvalExpression(BAD_CAST "//[@class='b-domik__nojs']", xpathCtx); //heres the parsing fails
问题是表达式CCD_ 4根本不起作用。我在firefox xpath
ext.和opera开发工具xpath
ext.中检查了它,在那里这个表达式可以完美地工作。
我还尝试获取其他具有属性的节点,但由于某种原因,ANY属性的xpath
失败了。我的方法有问题吗?此外,当我使用xmlRecover
加载树时,它在调试输出中会给我带来很多语法分析器错误。
好吧,我更多地使用了libxml2
函数,并使用"//*"
表达式来获取文档中的所有元素,但是!它只返回body标记的第一个子节点中的元素。这是yandex.ru dom树
因此,基本上它会获取第一个div "div class="b-line b-line_bar"
中的所有元素,但由于某种原因,它不会在<body>
的其他子节点中查找其他元素。
为什么会发生这种情况?也许xmlParseMemory
由于某种原因没有构建完整的树?有什么可能的解决方案可以解决这个问题吗。
表达式在任何地方都能工作,这真的很奇怪,因为它不是一个有效的XPath表达式。在轴规范(//
)之后,谓词(方括号中的条件)之前应该有一个nodetest(元素名称或*
)。
//*[@class='bdomik__nojs']
好吧,如果我的错误是使用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);
等等。
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- libxml2 XPath解析,无法按预期工作