1

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基本的に 1 つの div である クラスを持つノードを取得しようとしています。

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

問題は、表現//[@class='b-domik__nojs']がまったく機能しないことです。firefox xpathext.、およびopera developer tools xpathext.で確認しました。そこでは、この式は完全に機能します。

属性を持つ他のノードも取得しようとしましたが、何らかの理由xpathで ANY 属性が失敗しました。私の方法に何か問題がありますか?また、を使用してツリーをロードするxmlRecoverと、デバッグ出力に多くのパーサー エラーが表示されます。


わかりました、libxml2関数をもう少しいじって、"//*"式を使用してドキュメント内のすべての要素を取得しましたが、! body タグの最初の子ノードの要素のみが返されます。 これは yandex.ru dom ツリーです

したがって、基本的には最初の div のすべての要素を取得しますが、何らかの理由"div class="b-line b-line_bar"で他の子ノードの他の要素を探しません。<body>

なぜそれが起こることができますか?何らかのxmlParseMemory理由で完全なツリーを構築しないのでしょうか? これを修正する解決策はありますか。

4

2 に答える 2

1

有効な XPath 式ではないため、この式がどこでも機能するのは非常に奇妙です。軸指定 ( ) の後、述語 (角括弧内の条件) の前に//nodetest (要素名または ) が必要です。*

//*[@class='bdomik__nojs']
于 2013-08-08T14:38:08.500 に答える