I have the following XML structure:
<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>
And I would like to query it with XPATH. What I would like to do is get all the tile Nodes and then iterate over them to get all their names and other relevant information (using different XPATH queries).
Because XPATH expressions are to be ran on a Document, I have used the following nodeListToDoc()
function, provided in this answer to convert the result of an XPATH query (a NodeList) to a Document. This way I can first get all the Tiles, then iterate over them to get Tile specific information.
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;
}
What I first do is parse the file to a Document and then run the query to get a NodeList that contains all my Tiles. When I run the query //definitions/tile
I get a NodeList containing two Node items (I have verified this), which is correct. The result of applying nodeListToDoc()
looks like this.
<?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>
So far so good. Now things go bad. I want to iterate over the two nodes, make a NodeList of them, convert that NodeList to a Document and then run some queries over them. One of the queries is get the name of every tile. I thought the following code piece would do the trick:
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
}
However, when I print the resulting tree that attrdoc represents, I get, for the first iteration, the following result:
<?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>
This is incorrect. The child of the root element should be tile? Where did this element go?