0

私は次のXML構造を持っています:

<map name="testmap">
    <definitions>
        <tile name="ground"> <!-- a normal tile that has no special obstacles -->
            <centralObstacle>ground</centralObstacle>
            <neighbourObstacles>
                <north></north>
                <east></east>
                <south></south>
                <west></west>
            </neighbourObstacles>
        </tile>
        <tile name="wallE"> <!-- a ground tile with a wall obstacle at the east-->
            <centralObstacle>ground</centralObstacle>
            <neighbourObstacles>
                <north></north>
                <east>wall</east>
                <south></south>
                <west></west>
            </neighbourObstacles>
        </tile>
    </definitions>
</map>

そして、XPATHを使用してクエリを実行したいと思います。私がやりたいのは、すべてのタイルノードを取得してから、それらを反復処理して、すべての名前とその他の関連情報を取得することです(さまざまなXPATHクエリを使用)。

XPATH式はドキュメントで実行されるため、このnodeListToDoc()回答で提供されている次の関数を使用して、XPATHクエリ(NodeList)の結果をドキュメントに変換しました。このようにして、最初にすべてのタイルを取得し、次にそれらを反復処理してタイル固有の情報を取得できます。

private Document nodeListToDoc(NodeList nodes) throws ParserConfigurationException  
{
    Document newXmlDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
    Element root = newXmlDocument.createElement("root");
    newXmlDocument.appendChild(root);
    for (int i = 0; i < nodes.getLength(); i++) {
        Node node = nodes.item(i);
        Node copyNode = newXmlDocument.importNode(node, true);
        root.appendChild(copyNode);
    }
    return newXmlDocument;      
}

私が最初に行うことは、ファイルをドキュメントに解析してから、クエリを実行して、すべてのタイルを含むNodeListを取得することです。クエリを実行すると、//definitions/tile2つのノードアイテムを含むNodeListが取得されます(これを確認しました)。これは正しいです。塗った結果はnodeListToDoc()こんな感じ。

 <?xml version="1.0" encoding="UTF-16"?>
<root><tile name="ground"> <!-- a normal tile that has no special obstacles -->
            <centralObstacle>ground</centralObstacle>
            <neighbourObstacles>
                <north/>
                <east/>
                <south/>
                <west/>
            </neighbourObstacles>
        </tile><tile name="wallE"> <!-- a ground tile with a wall obstacle at the east-->
            <centralObstacle>ground</centralObstacle>
            <neighbourObstacles>
                <north/>
                <east>wall</east>
                <south/>
                <west/>
            </neighbourObstacles>
        </tile></root>

ここまでは順調ですね。今、事態は悪化します。2つのノードを反復処理し、それらのNodeListを作成し、そのNodeListをドキュメントに変換してから、いくつかのクエリを実行します。クエリの1つは、すべてのタイルの名前を取得することです。次のコードピースでうまくいくと思いました。

  for (int i = 0; i < nodes.getLength(); i++) { // iterate over the two nodes
            NodeList tile = (NodeList) nodes.item(i); // create a nodelist containing only the first node
            Document attrdoc = nodeListToDoc(tile); // convert it to a document
}

ただし、attrdocが表す結果のツリーを印刷すると、最初の反復で次の結果が得られます。

<?xml version="1.0" encoding="UTF-16"?>
<root> <!-- a normal tile that has no special obstacles -->
            <centralObstacle>ground</centralObstacle>
            <neighbourObstacles>
                <north/>
                <east/>
                <south/>
                <west/>
            </neighbourObstacles>
        </root>

これは正しくありません。ルート要素の子はタイルである必要がありますか?この要素はどこに行きましたか?

4

2 に答える 2

1

あなたは何を達成しようとしているのかを実際には説明していませんが、あなたの説明は Java+XPath がその仕事に適したツールであるかどうか疑問に思います。XQuery または XSLT でそれを行うことを検討しましたか?

于 2012-05-31T22:54:32.940 に答える
0

@Andyのコメントに+1。あなたの質問を読んだとき、あなたが本当に新しい文書を作りたいとは思えません。むしろ、既存の XML から情報を抽出する手段として使用しているだけです。

したがって、あなたのアプローチは、ノードから直接情報にアクセスすることです。たとえば、2 つのノードを反復処理するパッセージでは、次のようなことができます。

for (int i = 0; i < nodes.getLength(); i++) { // iterate over the two nodes
    NodeList node = nodes.item(i);
    if (node.getNodeType() == ELEMENT_NODE) {
        Element element = (Element) node;
        //from here, you can access element.getNodeValue(), element.getChildNodes(), etc.
    }    
}

newXmlDocumentさらに、複数の XPath クエリに戻って適用することもできます。これは、SAX パーサーを使用している場合のように、1 回で完了するわけではありません。

于 2012-05-31T20:28:34.203 に答える