2011-08-26 67 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()); 
     } 
    } 
}