2011-12-01 153 views
0

我想解析下面的xml。我可以轻松访问WeekNumber,但无法访问EmployeeRatesLevelA和EmployeeRatesLevelB的子项。目标是将这些保存到一个类,包含字段WeekNumber和ArrayLists,EmployeeRatesLevelA和EmployeeRatesLevelB的DataSet。 谢谢。Java - 使用DOM解析xml

<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; 
    } 

这给了我Weeknumber但我无法访问EmployeeRatesLevelA和EmployeeRatesLevelB。

想学习其他很酷的东西,但由于我是Java新手,而且xml文档非常小,所以DOM应该足够了。

+3

你的代码是什么? – talnicolas

+0

数据集有多大?它会只是一些小的记录或更大的东西? –

+0

就像对未来的建议一样 - 不要将DOM用于XML。有许多**更高效的技术 - [vtd-xml](http://vtd-xml.sourceforge.net/),SAX([Saxon](http://saxon.sourceforge.net/)) [XOM(http://www.xom.nu/) –

回答

4

如果你想使用DOM,我建议你从写一些帮助类开始,让你的工作更轻松。这是我最近为我个人使用而编写的。

让我们先从辅助类封装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; 
    } 
} 

现在是DataSet.java和Main.java如下:

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(); 
    } 
} 
+0

与[JAXB在不同的答案]中可以实现的答案相比,这个答案相当冗长(http://stackoverflow.com/questions/8345529/java-parsing-xml-using-dom#8345637) –

7

正如评论中所述,请向我们展示您的Java代码。您也可以考虑查看JAXB - Java绑定XML体系结构。这特别适用于将XML表示为Java对象。它可能不是你不管出于什么原因的解决方案是可行的,但绝对看一看:

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

的DataSet

下以下的域对象是你在你的问题描述:

目标是将这些保存到一个类DataSet,其中包含字段WeekNumber 和ArrayLists,EmployeeRatesLevelA和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; 

} 

演示

下面的代码演示了如何使用JAXB运行时对XML到/转换从域对象:

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); 
    } 

} 
+0

+1 - 我在你的答案中增加了一个工作的JAXB例子。我希望你不介意编辑。 –

+1

没有那么完美!谢谢你的加分。 – Shaun