0
        import java.io.IOException;
        import java.util.Vector;

        import javax.xml.parsers.DocumentBuilder;
        import javax.xml.parsers.DocumentBuilderFactory;

        import org.w3c.dom.Document;
        import org.w3c.dom.Element;
        import org.w3c.dom.Node;
        import org.w3c.dom.NodeList;
        import org.xml.sax.SAXException;

        import buildingInfo.Level;

        public class XmlParser {    

            public static void main(String[] args) {  
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                Vector<Level> vLvl = new Vector<Level>(30);
                try {
                    DocumentBuilder builder = factory.newDocumentBuilder();
                    Document doc = builder.parse("C:\\Users\\BeatriceGhetel\\workspace\\IPProject\\src\\configuration\\Configure.xml");
                    NodeList itemList = doc.getElementsByTagName("LEVEL");

                    for (int i = 0; i < itemList.getLength(); i++) {
                        Node it = itemList.item(i);
                        if (it.getNodeType()==Node.ELEMENT_NODE) {
                            Element el = (Element) it;
                            NodeList L = el.getChildNodes();
                            for (int j=0; j< L.getLength(); j++) {

                                Node n = L.item(j);
                                if (n.getNodeType()==Node.ELEMENT_NODE) {                           
                                    buildingInfo.Level Lvl = new         BuildingInfo.Level();
                                    if (n.getNodeName().matches("HEIGHT")) {
                                        Lvl.Height = Float.parseFloat(n.getTextContent());
                                    }
                                    System.out.println(Lvl.Height + " inaltime nivel");
                                    Element e = (Element) n;                            
                                }
                            }
                        }
                    }
                } catch (Exception ex){
                    ex.printStackTrace();
                }
            }       
        }

    <BUILDING>
    <LEVEL>
        <LABEL> 0 </LABEL>
        <HEIGHT> 2.5 </HEIGHT>
        <WIDTH> 9 </WIDTH>
        <LENGHT> 8 </LENGHT>
        <CAPACITY> 120 </CAPACITY>
        <ROOM>
            <LABEL> 1 </LABEL>
            <TYPE> NORMALROOM </TYPE>
            <HEIGHT> 2.5 </HEIGHT>
            <WIDTH> 5 </WIDTH>
            <LENGTH> 5 </LENGTH>
            <CAPACITY> 40 </CAPACITY>
            <SPRINKLER> YES </SPRINKLER>
            <SMOKEDETECTOR> YES </SMOKEDETECTOR>
            <EXTINGUISHERNUMBER> 2 </EXTINGUISHERNUMBER>
            <DOORNUMBER> 1 </DOORNUMBER>
            <DOOR>
                <ID> 1 </ID>
                <TYPE > EXTERNAL </TYPE >
                <CAPACITY> 2 </CAPACITY>
                <POSITION> NORTH </POSITION>
            </DOOR>
        </ROOM>   

I try to create a model of a building getting attributes from a XML document of configuration. The problem I have is that I cannot make a difference between the height of a room or height of a door, and it also doesn't always take the height, it sometimes take other values like length instead of height. I also need to figure out how to create a collection of rooms, and to create objects for the nested items like Doors.

2
  • I mention I've already gone trhough other related topics on stackoverflow Commented May 8, 2016 at 20:17
  • I mean, I actually need something to help me identify that 2.5 is the height of the LEVEL and to stop getting level attributes when I encounter the ROOM, and then to know that 2.5 (could be a different value to be more obvious) is the height of the room, so I could create different objects. Added this comment hoping that it may give you a better idea of what I need to do.Anyway, I'l try parsing the XML with Digester, as suggested in the first answer, maybe it will help solve my problem. Commented May 8, 2016 at 21:11

2 Answers 2

1

JAXB is the one of the simplest way to parse XML objects. Just defining the java class structure to match the XML structure will do the magic. It also supports Collections(Array of XML elements) in a much simpler way. I have developed the code to the parse the given XML(Altered XML little bit to show how collections in Level/Room/Door can also be handled). Hope it will help you.

XML File - Base.xml

<?xml version="1.0" encoding="UTF-8"?>
<BUILDING>
    <LEVEL>
        <LABEL>0</LABEL>
        <HEIGHT>2.5</HEIGHT>
        <WIDTH>9</WIDTH>
        <LENGHT>8</LENGHT>
        <CAPACITY>120</CAPACITY>
        <ROOM>
            <LABEL>1</LABEL>
            <TYPE>NORMALROOM</TYPE>
            <HEIGHT>2.5</HEIGHT>
            <WIDTH>5</WIDTH>
            <LENGTH>5</LENGTH>
            <CAPACITY>40</CAPACITY>
            <SPRINKLER>YES</SPRINKLER>
            <SMOKEDETECTOR>YES</SMOKEDETECTOR>
            <EXTINGUISHERNUMBER>2</EXTINGUISHERNUMBER>
            <DOORNUMBER>1</DOORNUMBER>
            <DOOR>
                <ID>1</ID>
                <TYPE>EXTERNAL</TYPE>
                <CAPACITY>2</CAPACITY>
                <POSITION>NORTH</POSITION>
            </DOOR>
            <DOOR>
                <ID>2</ID>
                <TYPE>EXTERNAL</TYPE>
                <CAPACITY>1</CAPACITY>
                <POSITION>SOUTH</POSITION>
            </DOOR>
        </ROOM>
        <ROOM>
            <LABEL>2</LABEL>
            <TYPE>DELUXEROOM</TYPE>
            <HEIGHT>2.5</HEIGHT>
            <WIDTH>5</WIDTH>
            <LENGTH>5</LENGTH>
            <CAPACITY>80</CAPACITY>
            <SPRINKLER>YES</SPRINKLER>
            <SMOKEDETECTOR>YES</SMOKEDETECTOR>
            <EXTINGUISHERNUMBER>2</EXTINGUISHERNUMBER>
            <DOORNUMBER>1</DOORNUMBER>
            <DOOR>
                <ID>3</ID>
                <TYPE>EXTERNAL</TYPE>
                <CAPACITY>2</CAPACITY>
                <POSITION>NORTH</POSITION>
            </DOOR>
            <DOOR>
                <ID>4</ID>
                <TYPE>EXTERNAL</TYPE>
                <CAPACITY>1</CAPACITY>
                <POSITION>SOUTH</POSITION>
            </DOOR>
        </ROOM>
    </LEVEL>
</BUILDING>

Building.java

@XmlRootElement(name = "BUILDING")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({ Level.class })
public class Building {

    @XmlElement(name = "LEVEL")
    private Level levels[];

    public Level[] getLevels() {
        return levels;
    }

    public void setLevels(Level[] levels) {
        this.levels = levels;
    }

    @Override
    public String toString() {
        return "Building [levels=" + Arrays.toString(levels) + "]";
    }

}

Door.java

@XmlRootElement(name = "DOOR")
@XmlAccessorType(XmlAccessType.FIELD)
public class Door {

    @XmlElement(name="ID")
    private String id;

    @XmlElement(name="TYPE")
    private String type;

    @XmlElement(name="CAPACITY")
    private String capacity;

    @XmlElement(name="POSITION")
    private String position;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getCapacity() {
        return capacity;
    }

    public void setCapacity(String capacity) {
        this.capacity = capacity;
    }

    public String getPosition() {
        return position;
    }

    public void setPosition(String position) {
        this.position = position;
    }


    @Override
    public String toString() {
        return "Door [id=" + id + ", type=" + type + ", capacity=" + capacity
                + ", position=" + position + "]";
    }
}

Level.java

@XmlRootElement(name="LEVEL")
@XmlSeeAlso({Room.class})
@XmlAccessorType(XmlAccessType.FIELD)
public class Level {

    @XmlElement(name="LABEL")
    private String Label;

    @XmlElement(name="HEIGHT")
    private String Height;

    @XmlElement(name="ROOM")
    private Room rooms[];

    public Room[] getRoom() {
        return rooms;
    }

    public void setRoom(Room[] room) {
        this.rooms = room;
    }

    public String getLabel() {
        return Label;
    }

    public void setLabel(String label) {
        Label = label;
    }

    public String getHeight() {
        return Height;
    }

    public void setHeight(String height) {
        Height = height;
    }

    @Override
    public String toString() {
        return "Level [Label=" + Label + ", Height=" + Height + ", rooms="
                + Arrays.toString(rooms) + "]";
    }
}

JAXBParser.java

public class JAXBParser {

    public static void main(String args[]) throws JAXBException{
        File file = new File("C:\\XMLParserDemo\\src\\Base.xml");
        JAXBContext jaxbContext = JAXBContext.newInstance(Building.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        Building building = (Building) jaxbUnmarshaller.unmarshal(file);
        System.out.println(building);


    }

Room.java

@XmlRootElement(name="ROOM")
@XmlSeeAlso({Door.class})
@XmlAccessorType(XmlAccessType.FIELD)
public class Room {

    @XmlElement(name="LABEL")
    private String label;

    @XmlElement(name="TYPE")
    private String type;    

    @XmlElement(name="HEIGHT")
    private String height;

    @XmlElement(name="WIDTH")
    private String width;

    @XmlElement(name="LENGTH")
    private String length;

    @XmlElement(name="CAPACITY")
    private String capacity;

    @XmlElement(name="SPRINKLER")
    private String sprinkler;

    @XmlElement(name="SMOKEDETECTOR")
    private String smokeDet;

    @XmlElement(name="EXTINGUISHERNUMBER")
    private String extNum;

    @XmlElement(name="DOORNUMBER")
    private String doorNumber;

    @XmlElement(name="DOOR")
    Door doors[];

    public Door[] getDoor() {
        return doors;
    }
    public void setDoor(Door[] door) {
        this.doors = door;
    }
    public String getHeight() {
        return height;
    }
    public void setHeight(String height) {
        this.height = height;
    }
    public String getWidth() {
        return width;
    }
    public void setWidth(String width) {
        this.width = width;
    }
    public String getLength() {
        return length;
    }
    public void setLength(String length) {
        this.length = length;
    }
    public String getCapacity() {
        return capacity;
    }
    public void setCapacity(String capacity) {
        this.capacity = capacity;
    }
    public String getSprinkler() {
        return sprinkler;
    }
    public void setSprinkler(String sprinkler) {
        this.sprinkler = sprinkler;
    }
    public String getSmokeDet() {
        return smokeDet;
    }
    public void setSmokeDet(String smokeDet) {
        this.smokeDet = smokeDet;
    }
    public String getExtNum() {
        return extNum;
    }
    public void setExtNum(String extNum) {
        this.extNum = extNum;
    }
    public String getDoorNumber() {
        return doorNumber;
    }
    public void setDoorNumber(String doorNumber) {
        this.doorNumber = doorNumber;
    }

    public String getLabel() {
        return label;
    }
    public void setLabel(String label) {
        this.label = label;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "Room [label=" + label + ", type=" + type + ", height=" + height
                + ", width=" + width + ", length=" + length + ", capacity="
                + capacity + ", sprinkler=" + sprinkler + ", smokeDet="
                + smokeDet + ", extNum=" + extNum + ", doorNumber="
                + doorNumber + ", doors=" + Arrays.toString(doors) + "]";
    }    

}
Sign up to request clarification or add additional context in comments.

6 Comments

Looks nice, each class is clear, without errors, jars from JAXB were succesfully integrated, but still, when I compile the project I get this big error (and can't get rid of it... searched the internet and other stack posts about it but wasn't successful): May 09, 2016 2:31:59 AM com.sun.xml.bind.v2.ClassFactory create0 INFO: No default constructor found on class java.util.logging.Level java.lang.NoSuchMethodException: java.util.logging.Level.<init>() at java.lang.Class.getConstructor0(Unknown Source) (and more other rows, had no space to insert them)
We have used a class named "Level.java" here in this example. I guess your code some how using the Logger level class. Check the imports and use the local Level.java file and dont import Logger level file. Hope this should be the problem.
If you not using logger in your project remove the import - "import java.util.logging"
I didn't use the logger class, but when I used Ctrl+Shift+O Eclipse imported something unnecessary that was import java.util.logging.Level;. Now it compiles and displays the right thing!
Also had a struggle accessing the data from a level, but succeeded by using Level[] L = building.getLevels(); for (Level level : L) { System.out.println(level.getLabel()); System.out.println(level.getHeight()); } just as a sample. Best answer, thank you a lot for your help!
|
1

I would never do this using the DOM Api directly. This use case is what e.g. commons-digester is made for: https://commons.apache.org/proper/commons-digester/guide/core.html

Also, Dom4J is a more Java-friendly way of handling DOM trees: http://dom4j.sourceforge.net/dom4j-1.6.1/guide.html, where you can use e.g. simple iterators for nested elements.

The standard W3C DOM API that you use was intended to have a common API between Java, C++ and JavaScript IIRC, so it's very complicated to use directly, as you have noticed.

3 Comments

Indeed it's complicated in the way I've tried. Thank you for your suggestions! I'll try them :)
I've tried to use digester and then dom4j but they both got me to the same point where DOM Api got me... I'll try JAXB as suggested in another answer. But if you have other hints I'm ready to listen and learn from them, maybe I didn't use them correctly.
I thought of JAXB, too. It's definitely much cleaner. Downside is that you need to write a lot more code, and it's a bit more overhead, but if that's ok for you, please continue this path.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.