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 xpath
ext.、およびopera developer tools xpath
ext.で確認しました。そこでは、この式は完全に機能します。
属性を持つ他のノードも取得しようとしましたが、何らかの理由xpath
で ANY 属性が失敗しました。私の方法に何か問題がありますか?また、を使用してツリーをロードするxmlRecover
と、デバッグ出力に多くのパーサー エラーが表示されます。
わかりました、libxml2
関数をもう少しいじって、"//*"
式を使用してドキュメント内のすべての要素を取得しましたが、! body タグの最初の子ノードの要素のみが返されます。 これは yandex.ru dom ツリーです
したがって、基本的には最初の div のすべての要素を取得しますが、何らかの理由"div class="b-line b-line_bar"
で他の子ノードの他の要素を探しません。<body>
なぜそれが起こることができますか?何らかのxmlParseMemory
理由で完全なツリーを構築しないのでしょうか? これを修正する解決策はありますか。