Reputation: 61
I am using DOM parser to access an XML document and retrieve some values. The problem is that while I need to load the values in a list in the exact order they appear in the XML, the parser returns the values of the childnodes in random order.
Here is my XML:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<scene id="mainMenu">
<sprite src="menubackground.png" position="0 0 0 0 0 0 200 200" visibility="true" name="background"/>
</scene>
</xml>
and the code I am using:
public class readXML2 {
public static void main(String [ ] args){
String[] temp = new String[4];
String sceneId = "mainMenu";
Document doc;
List<Node> sceneItems = new ArrayList<Node>();
DocumentBuilder builder;
File file = new File("C:\\Users\\manolaki\\Desktop\\assetsBACK.xml");
try{
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
doc = builder.parse(file);
doc.getDocumentElement().normalize();
for (int h = 0; h < doc.getElementsByTagName("scene").getLength(); h++){
if (doc.getElementsByTagName("scene").item(h).getAttributes().getNamedItem("id").getNodeValue().equals(sceneId)){
for (int t=0; t< doc.getElementsByTagName("scene").item(h).getChildNodes().getLength(); t++ )
if (doc.getElementsByTagName("scene").item(h).getChildNodes().item(t).getNodeType() != Node.TEXT_NODE)
sceneItems.add(doc.getElementsByTagName("scene").item(h).getChildNodes().item(t));
}
}
for (int i=0; i <sceneItems.size(); i++){
for (int j=0; j < 4/*sceneItems.get(i).getAttributes().getLength()*/; j++){
temp[j] = sceneItems.get(i).getAttributes().item(j).getNodeValue();
System.out.println(temp[j]);
}
}
}catch (Exception e){ e.printStackTrace(); }
}
}
The values appear in the console like this:
background
0 0 0 0 0 0 200 200
menubackground.png
true
But I need This:
menubackground.png
0 0 0 0 0 0 200 200
true
background
I think DOM reads the XML in a tree structure but I am not sure how exactly its working and how I can get the values in the right order constantly for different childnodes.
Upvotes: 0
Views: 1034
Reputation: 101
If you need the order, use actual child elements, not attributes, like this:
<sprite>
<src>menubackground.png</src>
<position>0 0 0 0 0 0 200 200</position>
<visibility>true</visibility>
<name>background</name>
</sprite>
(If you are not in the position to define the structure of the XML, then you may try implementing a simple parser yourself to work around the design flaw - if advanced XML features are not expected in the input.)
Edit: What about loading the attributes into a java object, then you can output them as you like.
Upvotes: 0
Reputation: 122374
Per the XML specs the attributes of an element are a set of name/value pairs, with no defined ordering. A parser or DOM API is free to return them in any order it wants to, in fact the JavaDoc for NamedNodeMap
states that
NamedNodeMap
s are not maintained in any particular order. Objects contained in an object implementingNamedNodeMap
may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of aNamedNodeMap
, and does not imply that the DOM specifies an order to these Nodes.
You could dump the NamedNodeMap
into a List
or an array and sort that lexicographically by node name, which would give you a consistent order across all the elements, but there's no way to know the order in which the attributes were specified in the original XML source via the DOM API.
Upvotes: 1