2011-12-01 122 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