0

XPath でサイトマップを読みたいのですが、うまくいきません。ここに私のコードがあります:

private void evaluate2(String src){
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true); 
    try{
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new ByteArrayInputStream(src.getBytes()));

        System.out.println(src);

        XPathFactory xp_factory = XPathFactory.newInstance();

        XPath xpath = xp_factory.newXPath();

        XPathExpression expr = xpath.compile("//url/loc");

        Object result = expr.evaluate(doc, XPathConstants.NODESET);


        NodeList nodes = (NodeList) result;

        System.out.println(nodes.getLength());


        for (int i = 0; i < nodes.getLength(); i++) {
            items.add(nodes.item(i).getNodeValue());
            System.out.println(nodes.item(i).toString()); 
        }         
    }catch(Exception e){
        System.out.println(e.getMessage());
    }
}

サイトマップのリモート ソースを取得する前に、それが変数 src を介して evaluate2 に渡されます。そして、System.out.println(nodes.getLength());表示 0 このクエリは PHP で機能するため、私の xpath クエリは機能しています。私のコードにエラーが表示されますか?

ありがとう

4

3 に答える 3

1

名前空間を認識するパーサーを使用してサイトマップを解析しますが (これfactory.setNamespaceAware(true)が機能します)、名前空間リゾルバーを使用しない (または名前空間を参照しない) XPath を使用してサイトマップにアクセスしようとします。

最も簡単な解決策は、パーサーを名前空間を認識しないように構成することです。自己完結型のサイトマップを解析しているだけであれば、問題にはなりません。

コードのもう 1 つの問題は、サイトマップのコンテンツを文字列として渡し、プラットフォームの既定のエンコーディングを使用してその文字列を変換することです。これは、プラットフォームのデフォルトのエンコーディングが、サーバーから取得した実際のバイトのエンコーディングと一致する限り機能します (プラットフォームのデフォルトのエンコーディングを使用して文字列も作成したと仮定します)。そうでない場合、変換エラーが発生する可能性があります。

于 2012-12-20T18:50:23.973 に答える
1

入力には名前空間があると思います。そのため、xpath オブジェクトの namespaceContext を初期化し、プレフィックスを使用して xpath を変更する必要があります。つまり、//usr/loc は //ns:url/ns:loc である必要があり、名前空間プレフィックス バインディングを名前空間オブジェクトに追加します。

apache common で利用可能な NamespaceContext 実装を見つけることができます。http://ws.apache.org/commons/util/apidocs/index.html ws-commons-utils

NamespaceContextImpl namespaceContextObj = new NamespaceContextImpl();
    nsContext.startPrefixMapping("ns", "http://sitename/xx");
xpath.setNamespaceContext(namespaceContextObj);

XPathExpression expr = xpath.compile("//ns:url/ns:loc");

どの名前空間が来るかわからない場合は、ドキュメント自体からそれらを取得できますが、それがあまり役立つとは思えません。ここにはいくつかのハウツーがあります http://www.ibm.com/developerworks/xml/library/x-nmspccontext/index.html

于 2012-12-20T19:09:18.217 に答える
0

コードにエラーが見当たらないので、問題はソースにあると思います。ソース ファイルにこの要素が含まれていますか?

おそらく、このコードを使用してドキュメント内の文字列を解析することができます

builder.parse(new InputSource(new StringReader(xml)));
于 2012-12-20T18:24:15.643 に答える