2011-08-26 68 views
3

我想通過DOM XML文件遍歷檢索的(名稱,值)對所有的目的:遍歷DOM樹來獲得(名稱,值)對屬性和葉節點的

  1. 屬性名稱和值;
  2. 所有葉節點名稱及其文本內容;

因此,考慮下面的XML文件爲例:

<?xml version="1.0" encoding="UTF-8"?> 
<title text="title1"> 
    <comment id="comment1"> 
     <data> abcd </data> 
     <data> efgh </data> 
    </comment> 
    <comment id="comment2"> 
     <data> ijkl </data> 
     <data> mnop </data> 
     <data> qrst </data> 
    </comment> 
</title> 

我想作爲名稱值對什麼是:

text=title1 
id=comment1 
data=abcd 
data=efgh 
id=commment2 
data=ijkl 
data=mnop 
data=qrst 
+0

我很高興!您可能想要使用Java DOM API。 http://java.sun.com/developer/codesamples/xml.html#dom – adatapost

+0

爲什麼不嘗試使用XMLBean,而我剛剛看到您在最近提出的問題中詢問過有關XPath的問題?沒有上下文的名稱值對不能用xml表示數據。 –

+0

@Clark這是真的,但我不只想獲得(名稱,值)對,而是以這種方式進行遍歷,並且任何時候遇到這些對時,我都會做一些更多的處理... – Larry

回答

2

如何像:

String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
     "<title text=\"title1\">\n" + 
     " <comment id=\"comment1\">\n" + 
     "  <data> abcd </data>\n" + 
     "  <data> efgh </data>\n" + 
     " </comment>\n" + 
     " <comment id=\"comment2\">\n" + 
     "  <data> ijkl </data>\n" + 
     "  <data> mnop </data>\n" + 
     "  <data> qrst </data>\n" + 
     " </comment>\n" + 
     "</title>\n"; 

    try { 
     DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
     Document doc = builder.parse(new InputSource(new StringReader(xml))); 

     DocumentTraversal traversal = (DocumentTraversal) doc; 

     NodeIterator iterator = traversal.createNodeIterator(
      doc.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true); 

     for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) { 
      //System.out.println("Element: " + ((Element) n).getTagName()); 
      String tagname = ((Element) n).getTagName(); 
      if(tagname.equals("title")) { 
       System.out.println("text=" + ((Element)n).getAttribute("text")); 
      } 
      else if(tagname.equals("comment")) { 
       System.out.println("id=" + ((Element)n).getAttribute("id")); 
      } 
      else if(tagname.equals("data")) { 
       System.out.println("data=" + ((Element)n).getTextContent()); 
      } 
      else { 
       System.out.println("Unhandled element"); 
      } 
     } 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

好的,所以你不滿意,這個怎麼樣:

String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
     "<title text=\"title1\">\n" + 
     " <comment id=\"comment1\">\n" + 
     "  <data> abcd </data>\n" + 
     "  <data> efgh </data>\n" + 
     " </comment>\n" + 
     " <comment id=\"comment2\">\n" + 
     "  <data> ijkl </data>\n" + 
     "  <data> mnop </data>\n" + 
     "  <data> qrst </data>\n" + 
     " </comment>\n" + 
     "</title>\n"; 

    try { 
     DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
     Document doc = builder.parse(new InputSource(new StringReader(xml))); 

     DocumentTraversal traversal = (DocumentTraversal) doc; 

     NodeIterator iterator = traversal.createNodeIterator(
      doc.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true); 

     for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) { 
      //System.out.println("Element: " + ((Element) n).getTagName()); 
      String tagname = ((Element) n).getTagName(); 

      NamedNodeMap map = ((Element)n).getAttributes(); 
      if(map.getLength() > 0) { 

       for(int i=0; i<map.getLength(); i++) { 
        Node node = map.item(i); 
        System.out.println(node.getNodeName() + "=" + node.getNodeValue()); 
       } 
      } 
      else { 
       System.out.println(tagname + "=" + ((Element)n).getTextContent()); 
      } 
     } 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
+0

謝謝,但我實際上需要一個通用的解決方案。即給定任意的XML文件,它將遍歷所有屬性(名稱,值)對和所有葉節點(名稱,文本內容)對... – Larry

+0

您不能這樣做,因爲您的某些數據存儲在屬性,一些在文字內容中。你要麼讓你的xml總是在同一個地方存儲你想要的東西,要麼你做我所展示的東西。 – nuzz

+0

對於每個節點,您不可以有一種算法,它會提取所有屬性的名稱 - 值對,然後爲每個子節點遞歸,直到我們有一個節點,在節點中我們提取節點名稱和文本內容... – Larry

4

更簡單的解決方案可能是使用XPath來提取所有名稱值對,如下例所示。您也可以跳過DOM構造並直接在InputSource上調用評估。 XPath表達式

//@* | //*[not(*)] 

匹配所有屬性和所有沒有任何子節點的節點的聯合。

import java.io.StringReader; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.xpath.XPath; 
import javax.xml.xpath.XPathConstants; 
import javax.xml.xpath.XPathFactory; 
import org.w3c.dom.Document; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 
import org.xml.sax.InputSource; 

public class Test { 

    private static final String xml = "<title text='title1'>\n" 
      + " <comment id='comment1'>\n" 
      + " <data> abcd </data>\n" 
      + " <data> efgh </data>\n" 
      + " </comment>\n" 
      + " <comment id='comment2'>\n" 
      + " <data> ijkl </data>\n" 
      + " <data> mnop </data>\n" 
      + " <data> qrst </data>\n" 
      + " </comment>\n" 
      + "</title>\n"; 

    public static void main(String[] args) throws Exception { 
     DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
     Document doc = builder.parse(new InputSource(new StringReader(xml))); 

     XPathFactory xpf = XPathFactory.newInstance(); 
     XPath xp = xpf.newXPath(); 
     NodeList nodes = (NodeList)xp.evaluate("//@* | //*[not(*)]", doc, XPathConstants.NODESET); 

     System.out.println(nodes.getLength()); 

     for (int i=0, len=nodes.getLength(); i<len; i++) { 
      Node item = nodes.item(i); 
      System.out.println(item.getNodeName() + " : " + item.getTextContent()); 
     } 
    } 
}