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 查询)。

因为要在 Document 上运行 XPATH 表达式,所以我使用了nodeListToDoc()答案中提供的以下函数,将 XPATH 查询(NodeList)的结果转换为 Document。这样我可以首先获取所有的 Tile,然后遍历它们以获取 Tile 的特定信息。

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;      
}

我首先要做的是将文件解析为 Document,然后运行查询以获取包含我所有 Tiles 的 NodeList。当我运行查询时,//definitions/tile我得到一个包含两个节点项的 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>

到目前为止,一切都很好。现在事情变糟了。我想遍历这两个节点,制作它们的 NodeList,将该 NodeList 转换为 Document,然后对它们运行一些查询。其中一个查询是获取每个图块的名称。我认为以下代码可以解决问题:

  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>

这是不正确的。根元素的子元素应该是tile?这个元素去哪了?

4

2 回答 2

1

您并没有真正解释您要实现的目标,但您的描述确实让我想知道 Java+XPath 是否适合这项工作。您是否考虑过在 XQuery 或 XSLT 中这样做?

于 2012-05-31T22:54:32.940 回答
0

+1 @Andy 的评论。当我阅读您的问题时,在我看来您并不是真的想制作一个新文件。相反,您只是将它用作从现有 XML 中提取信息的一种方式。

因此,您的方法是直接从节点访问信息。例如,在您遍历两个节点的段落中,您可以执行以下操作:

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 解析器时那样。

于 2012-05-31T20:28:34.203 回答