0

xerces および xqilla ライブラリを使用して、XPATH2 で html ドキュメントから特定のノードを抽出したいのですが、有効な XPATH 式を構築できないか、コードがどこか間違っています。

私の現在のコード:

#include <iostream>
#include <string>

#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationRegistry.hpp>
#include <xercesc/dom/DOMConfiguration.hpp>

#include <xercesc/dom/DOMXPathExpression.hpp>
#include <xercesc/dom/DOMXPathResult.hpp>
#include <xercesc/dom/DOMLSParser.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMLSSerializer.hpp>
#include <xercesc/dom/DOMLSOutput.hpp>

#include <xercesc/sax/SAXParseException.hpp>
#include <xercesc/sax/ErrorHandler.hpp>

#include <xercesc/framework/StdOutFormatTarget.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/framework/Wrapper4InputSource.hpp>

#include <xercesc/util/XMLString.hpp>

#include <xqilla/xqilla-dom3.hpp>
#include <xercesc/parsers/AbstractDOMParser.hpp>
using namespace std;


const char document[] = { 0x3c, 0x21, 0x44, 0x4f, 0x43, .....,  0x6c, 0x3e, 0x0a, 0x00 };

int main() {

    // init xerces and xqilla engines
    XQillaPlatformUtils::initialize();

    // retrieve xqilla DOMImpl.
    xercesc::DOMImplementation* xqilla_impl
        = xercesc::DOMImplementationRegistry::getDOMImplementation(X("XPath2 3.0"));

    {
        // create DOMLSParser
        AutoRelease<xercesc::DOMLSParser> parser(xqilla_impl->createLSParser(xercesc::DOMImplementationLS::MODE_SYNCHRONOUS, 0));
        xercesc::DOMConfiguration *config = parser->getDomConfig();
        config->setParameter(xercesc::XMLUni::fgXercesScannerName, xercesc::XMLUni::fgWFXMLScanner);

        // retrieve lesson page:
        string str(document);

        xercesc::Wrapper4InputSource* wrapper =
                new xercesc::Wrapper4InputSource(
                new xercesc::MemBufInputSource((XMLByte*) str.c_str(), (XMLSize_t) str.length(), "index.html", false));


        // create DOM structure:
        xercesc::DOMDocument* dom = parser->parse(wrapper);

        AutoRelease<xercesc::DOMXPathExpression> expression(
            dom->createExpression(xercesc::XMLString::transcode("html/head"), 0)
        );

        AutoRelease<xercesc::DOMXPathResult> result(expression->evaluate(
            dom, xercesc::DOMXPathResult::ITERATOR_RESULT_TYPE, 0
        ));

        cout << result->iterateNext() << endl; // output is always 0
    }

    XQillaPlatformUtils::terminate();

    return 0;
}

何を変更する必要がありますか?

編集:

確認したい HTML ファイルはファイルの大きなコレクションであるため、プログラムや XPATH 式をテストするために小さなサンプル ファイルを作成しました。

  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml" >
  <head>
    <title>Some title</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="title" content="Some title" />
    <meta name="keywords" content="Keywords" />
    <meta name="description" content="A short description" />
  </head>
  <body>
    <p>
      Lorem ipsum dolor sit amet, consetetur sadipscing elitr,
      sed diam nonumy <b>eirmod <u>tempor</u> invidunt ut</b> labore et dolore<br />
      magna aliquyam erat, sed diam voluptua. At vero eos et accusam
      et justo duo dolores et ea rebum. Stet clita kasd gubergren,<br />
      no sea takimata sanctus est Lorem ipsum dolor sit amet.
    </p>
  </body>
</html>

これでも、私のプログラムは私の XPATH 式を持つノードを見つけられません。



私の問題に対して 2 つの準最適な解決策を見つけることができました

  • 1. 解決策:
    「*:html/*:head/*:title/text()」のような名前空間を気にしない XPath 式を使用します。
  • 2. 解決策:
    パーサーで DOM 名前空間をオフにします:
    config->setParameter(xercesc::XMLUni::fgDOMNamespaces, false);

名前のない DOM 名前空間のカスタム プレフィックスを手動で設定する方法が見つかった場合、または空のプレフィックスを明示的に指定できる XPath 式があった場合、私はより幸せになるでしょうが、少なくともドキュメントを処理できるようになりました。

4

1 に答える 1

0

および要素は名前空間にhtmlありheadますが、XPath は名前空間のない要素を探しています。プレフィックスを使用して XHTML 名前空間に"h:html/h:head"バインドします。"h"XQilla API でこのバインドを行う方法は正確にはわかりませんが、それを行う方法はいくつかあります。

于 2015-04-22T08:23:49.090 に答える