Java - Parsing xml using DOM

2020-02-07 10:22发布

I am trying to parse the following xml. I can access the WeekNumber easily but cannot access the children for EmployeeRatesLevelA and EmployeeRatesLevelB. The goal is to save these to a class, DataSet with fields WeekNumber and ArrayLists, EmployeeRatesLevelA and EmployeeRatesLevelB. Thanks.

<DataSet ActiveFrom="2011/04/06">  
    <WeekNumber>8</WeekNumber>  
    <EmployeeRatesLevelA>  
        <Rate>0</Rate>  
        <Rate>0.12</Rate>  
    </EmployeeRatesLevelA>  
    <EmployeeRatesLevelB>  
        <Rate>0.15</Rate>  
        <Rate>0.20</Rate>  
    </EmployeeRatesLevelB>  
</DataSet>  


    Document doc = loadXml("data.xml");  
    NodeList nodeList = doc.getElementsByTagName("DataSet");  
    for (int i = 0; i < nodeList.getLength(); i++) {  
        Node node = nodeList.item(i);  
        if (node.getNodeType() == Node.ELEMENT_NODE) {  
            Element element = (Element) node;  
            NodeList weekNumberList = element.getElementsByTagName("WeekNumber");  
            Element weekElement = (Element) weekNumberList.item(0);  
            NodeList textElementList = weekElement.getChildNodes();
            System.out.println("Weeknumber:"+ ((Node)textElementList.item(0)).getNodeValue().trim());
    }

    public static Document loadXml(String file) {
        try {
           return (DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(file)));
        } catch (SAXException e) {
        e.printStackTrace();
        } catch (IOException e) {
        e.printStackTrace();
        } catch (ParserConfigurationException e) {
        e.printStackTrace();
        }
        return null;
    }

This gives me the Weeknumber but I am unable to access EmployeeRatesLevelA and EmployeeRatesLevelB.

Would like to learn other cool stuff but as I am new to Java and the xml document is really small, DOM should suffice.

标签: java xml dom
4条回答
倾城 Initia
2楼-- · 2020-02-07 10:55

Element.getElementsByTagName("EmployeeRatesLevelA") where Element should be DataSet. Or you can use http://java.sun.com/javase/6/docs/api/org/w3c/dom/Node.html#getChildNodes()

then filter all the childs until you find the ones you want to.

查看更多
够拽才男人
3楼-- · 2020-02-07 11:06

I quite love groovy for these things, particularly if it's a one off to load stuff into a database:

http://groovy.codehaus.org/Reading+XML+using+Groovy%27s+XmlSlurper

查看更多
甜甜的少女心
4楼-- · 2020-02-07 11:18

If you want to use DOM, I suggest you to start by writing some helper classes to make your work easier. Here is one I written recently for my personal use.

Let's start with the helper classes in package xml.utils

XmlException.java

package xml.utils;

public class XmlException extends Exception {
    private static final long serialVersionUID = 1L;

    public XmlException(String message, Throwable cause)  {
        super(message, cause);
    }

    public XmlException(String message)  {
        super(message);
    }

    public XmlException(Throwable cause)  {
        super(cause);
    }
}

XmlDocument.java

package xml.utils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

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

public class XmlDocument {
    private Document document;

    public XmlNode parse(InputStream is) throws XmlException {
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            document = dBuilder.parse(is);
            document.getDocumentElement().normalize();

            XmlNode node = new XmlNode(document.getDocumentElement());
            return node;
        } catch (ParserConfigurationException e) {
            throw new XmlException("Error in configuration of XML parser", e);
        } catch (SAXException e) {
            throw new XmlException("Error in parsing XML document", e);
        } catch (IOException e) {
            throw new XmlException("Error in reading InputStream", e);
        }
    }

    public XmlNode parse(String uri) throws XmlException {
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            document = dBuilder.parse(uri);
            document.getDocumentElement().normalize();

            XmlNode node = new XmlNode(document.getDocumentElement());
            return node;
        } catch (ParserConfigurationException e) {
            throw new XmlException("Error in configuration of XML parser", e);
        } catch (SAXException e) {
            throw new XmlException("Error in parsing XML document", e);
        } catch (IOException e) {
            throw new XmlException("Error in opening URI", e);
        }
    }

    public XmlNode parse(File file) throws XmlException {
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            document = dBuilder.parse(file);
            document.getDocumentElement().normalize();

            XmlNode node = new XmlNode(document.getDocumentElement());
            return node;
        } catch (ParserConfigurationException e) {
            throw new XmlException("Error in configuration of XML parser", e);
        } catch (SAXException e) {
            throw new XmlException("Error in parsing XML document", e);
        } catch (IOException e) {
            throw new XmlException("Error in opening file", e);
        }
    }

    public void write(OutputStream os, XmlNode node) throws XmlException {
        try {
            if (document == null) {
                document = createNewDocument();
            }
            document.appendChild(node.getNode());

            // write the content into xml file
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(document);
            StreamResult result = new StreamResult(os);

            transformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
            throw new XmlException("Error in configuration of XML writer", e);
        } catch (TransformerException e) {
            throw new XmlException("Error in writing XML", e);
        }
    }

    public void write(File file, XmlNode node) throws XmlException {
        try {
            if (document == null) {
                document = createNewDocument();
            }
            document.appendChild(node.getNode());

            // write the content into xml file
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(document);
            StreamResult result = new StreamResult(file);

            transformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
            throw new XmlException("Error in configuration of XML writer", e);
        } catch (TransformerException e) {
            throw new XmlException("Error in writing XML", e);
        }
    }



    public void write(Writer writer, XmlNode node) throws XmlException {
        try {
            if (document == null) {
                document = createNewDocument();
            }
            document.appendChild(node.getNode());

            // write the content into xml file
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(document);
            StreamResult result = new StreamResult(writer);

            transformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
            throw new XmlException("Error in configuration of XML writer", e);
        } catch (TransformerException e) {
            throw new XmlException("Error in writing XML", e);
        }
    }

    private Document createNewDocument() throws XmlException {
        try {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            return dBuilder.newDocument();
        } catch (ParserConfigurationException e) {
            throw new XmlException("Error in configuration of XML parser", e);
        }
    }

    public XmlNode createNode(String nodeName) throws XmlException {
        if (document == null) {
            document = createNewDocument();
        }
        XmlNode node = new XmlNode(this, document.createElement(nodeName));
        return node;
    }

    XmlNode createNode(String nodeName, String nodeValue) throws XmlException {
        if (document == null) {
            document = createNewDocument();
        }
        Element node = document.createElement(nodeName);
        node.appendChild(document.createTextNode(nodeValue));

        return new XmlNode(this, node);
    }
}

XmlNode.java

package xml.utils;

import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XmlNode {
    private Element node;
    private XmlDocument parent;

    XmlNode(Element node) {
        this.node = node;
        this.parent = null;
    }

    XmlNode(XmlDocument parent, Element node) {
        this.node = node;
        this.parent = parent;
    }

    Node getNode() {
        return node;
    }

        public String getNodeValue() {
            return node.getTextContent();
        }

    public XmlDocument getParent() {
        return parent;
    }

    public void setParent(XmlDocument parent) {
        this.parent = parent;
    }

    public List<XmlNode> getChildNodes() {
        List<XmlNode> list = new ArrayList<XmlNode>();
        NodeList nodeList = node.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node n = nodeList.item(i);
            if (n.getNodeType() == Node.ELEMENT_NODE) {
                list.add(new XmlNode((Element) n));
            }
        }

        return list;
    }

    public XmlNode getFirstChild() {
        return getChildNodes().get(0);
    }

    public XmlNode getLastChild() {
        List<XmlNode> childs = getChildNodes();
        if (childs.size() == 0)
            return null;

        return childs.get(childs.size() - 1);
    }

    public List<XmlNode> getNodesByTagName(String tagName) {
        List<XmlNode> list = new ArrayList<XmlNode>();
        NodeList nodeList = node.getElementsByTagName(tagName);
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node n = nodeList.item(i);
            if (n.getNodeType() == Node.ELEMENT_NODE) {
                list.add(new XmlNode((Element) n));
            }
        }

        return list;
    }

    public XmlNode getFirstNodeByTagName(String tagName) {
        return getNodesByTagName(tagName).get(0);
    }

    public String getTagValue(String tagName) throws XmlException {
        NodeList tagList = node.getElementsByTagName(tagName);
        if (tagList.getLength() == 0)
            throw new XmlException("Tag: '" + tagName + "' not present");

        NodeList nlList = tagList.item(0).getChildNodes();       
        Node nValue = (Node) nlList.item(0);

        return nValue.getNodeValue();
    }

    public String getAttributeValue(String attributeName) {
        return node.getAttribute(attributeName);
    }

    public String getNodeName() {
        return node.getTagName();
    }

    public void setAttribute(String name, String value) throws XmlException {
        if (parent == null) 
            throw new XmlException("Parent node not present.");

        node.setAttribute(name, value);
    }

    public void setTag(String name, String value) throws XmlException {
        if (parent == null) 
            throw new XmlException("Parent node not present.");

        XmlNode xmlNode = parent.createNode(name, value);
        node.appendChild(xmlNode.node);
    }

    public void addChildNode(XmlNode xmlNode) throws XmlException {
        if (parent == null) 
            throw new XmlException("Parent node not present.");

        node.appendChild(xmlNode.node);
    }

    public XmlNode addChildNode(String nodeName) throws XmlException {
        if (parent == null) 
            throw new XmlException("Parent node not present.");

        XmlNode child = parent.createNode(nodeName);
        node.appendChild(child.getNode());

        return child;
    }
}

Now the DataSet.java and Main.java are as follows:

DataSet.java

package tests;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import xml.utils.XmlDocument;
import xml.utils.XmlException;
import xml.utils.XmlNode;

public class DataSet {
    private int weekNumber;
    private List<Float> employeeRatesLevelA;
    private List<Float> employeeRatesLevelB;

    public DataSet(File xml) throws XmlException {
        employeeRatesLevelA = new ArrayList<Float>();
        employeeRatesLevelB = new ArrayList<Float>();

        loadFromXml(xml);
    }

    private void loadFromXml(File xml) throws XmlException {
        XmlDocument document = new XmlDocument();
        XmlNode root = document.parse(xml);

        weekNumber = Integer.parseInt(root.getTagValue("WeekNumber"));

        XmlNode ratesLevelNode = root.getNodesByTagName("EmployeeRatesLevelA").get(0);
        List<XmlNode> rates = ratesLevelNode.getNodesByTagName("Rate");
        for (XmlNode xmlNode : rates) {
            employeeRatesLevelA.add(Float.parseFloat(xmlNode.getNodeValue()));
        }

        ratesLevelNode = root.getNodesByTagName("EmployeeRatesLevelB").get(0);
        rates = ratesLevelNode.getNodesByTagName("Rate");
        for (XmlNode xmlNode : rates) {
            employeeRatesLevelB.add(Float.parseFloat(xmlNode.getNodeValue()));
        }
    }

    public void display() {
        System.out.println("WeekNumber: " + weekNumber);
        System.out.println("Level A");
        for (Float rate : employeeRatesLevelA) {
            System.out.println("\tRate: " + rate);
        }

        System.out.println("Level B");
        for (Float rate : employeeRatesLevelB) {
            System.out.println("\tRate: " + rate);
        }
    }
}

Main.java

package tests;

import java.io.File;
import java.io.IOException;
import org.xml.sax.SAXException;
import xml.utils.XmlException;

public class Main {
    public static void main(String[] args) throws SAXException, IOException, XmlException {
        File dataFile = new File("/home/jomit/data.xml");
        DataSet dataSet = new DataSet(dataFile);
        dataSet.display();
    }
}
查看更多
做个烂人
5楼-- · 2020-02-07 11:22

As mentioned in the comments, please show us your Java code. You may also want to consider looking at JAXB - the Java Architecture for XML Binding. This is specifically geared towards representing XML as Java objects. It may not be feasible for your solution for whatever reason, but definitely take a look:

http://jaxb.java.net/tutorial/

DataSet

The following domain object below is what you described in your question:

The goal is to save these to a class, DataSet with fields WeekNumber and ArrayLists, EmployeeRatesLevelA and EmployeeRatesLevelB.

package forum8345529;

import java.util.List;
import javax.xml.bind.annotation.*;

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

    @XmlElement(name="WeekNumber")
    private int weekNumber;

    @XmlElementWrapper(name="EmployeeRatesLevelA")
    @XmlElement(name="Rate")
    private List<Float> employeeRatesLevelA;

    @XmlElementWrapper(name="EmployeeRatesLevelB")
    @XmlElement(name="Rate")
    private List<Float> employeeRatesLevelB;

}

Demo

The following code demonstrates how to use the JAXB runtime to convert your XML to/from your domain objects:

package forum8345529;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception{
        JAXBContext jc = JAXBContext.newInstance(DataSet.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum8345529/input.xml");
        DataSet dataSet = (DataSet) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(dataSet, System.out);
    }

}
查看更多
登录 后发表回答