user3433393
user3433393

Reputation: 61

How can I retrieve childnodes of a node in the order they appear in the XML document?

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

Answers (2)

Peter T&#246;lgyesi
Peter T&#246;lgyesi

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

Ian Roberts
Ian Roberts

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

NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, 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

Related Questions