c++ - libxml2 xpath 解析,无法按预期工作

标签 c++ qt parsing xpath libxml2

我决定使用 libxml2我的 qt 应用程序的解析器,我卡在了 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 的节点这基本上是一个分区。

xpathObj = xmlXPathEvalExpression(BAD_CAST "//[@class='b-domik__nojs']", xpathCtx); //heres the parsing fails

问题是表达式 //[@class='b-domik__nojs']根本不起作用。我在 firefox 里查过了 xpath分机,并在 Opera 开发人员工具中 xpath分机。在那里这个表达式完美地工作。

我还尝试获取其他具有属性的节点,但出于某种原因 xpath对于任何属性失败。我的方法有问题吗?此外,当我使用 xmlRecover 加载一棵树时,它在调试输出中给了我很多解析器错误。


好的,我玩了一下我的 libxml2更多功能和使用"//*"获取文档中所有元素的表达式,但是!它只返回 body 标签的第一个子节点中的元素。 This is the yandex.ru dom tree

所以基本上它获取了第一个 div "div class="b-line b-line_bar" 中的所有元素, 但不在 <body> 的其他子节点中查找其他元素因为某些原因。

为什么会这样?也许xmlParseMemory出于某种原因没有 build 一棵完整的树?是否有任何可能的解决方案来解决此问题。

最佳答案

这个表达式在任何地方都有效,这真的很奇怪,因为它不是一个有效的 XPath 表达式。在轴规范(//)之后,在谓词(方括号中的条件)之前应该有一个nodetest(元素名称或*)。

//*[@class='bdomik__nojs']

关于c++ - libxml2 xpath 解析,无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18128381/

相关文章:

python - QT 消失第二个窗口

c++ - 列表框对齐问题

c++ - 使用来自 C++ 的训练有素的 caffe net 得到错误的结果

c++ - 连接c++服务器时,flash socket发送错误数据

c++ - clang 静态分析器是否因从 unique_ptr 列表中弹出前面而感到困惑?

qt - 如何将matlab与QT集成

c# - 将逗号添加到 .NET 2.0 文本字符串中的十进制数

java - 如何获取给定关键字的搜索结果(html 格式)并针对 Talend 中的所有搜索结果页面迭代它?

java - 如何使用android过滤网页并获取所需数据

C++ 歌曲打印问题