java 遍历 DOM 树以获取(名称,值)属性和叶节点对
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7199897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Traversing a DOM tree to get (name,value) pairs of attributes and leaf nodes
提问by Larry
I want to traverse through an XML file in DOM for the purpose of retrieving as (name,value) pairs all:
我想遍历 DOM 中的 XML 文件,以便检索为 (name,value) 对:
- Attribute names and values;
- All leaf node names and their text content;
- 属性名称和值;
- 所有叶节点名称及其文本内容;
So given the following XML file as an example:
因此以以下 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>
What I want as name value pairs are:
我想要的名称值对是:
text=title1
id=comment1
data=abcd
data=efgh
id=commment2
data=ijkl
data=mnop
data=qrst
回答by J?rn Horstmann
An easier solution might be to use XPath to extract all name value pairs as in the following example. You could also skip the DOM construction and call evaluate directly on the InputSource
. The XPath expression
更简单的解决方案可能是使用 XPath 提取所有名称值对,如下例所示。您也可以跳过 DOM 构造并直接在InputSource
. XPath 表达式
//@* | //*[not(*)]
matches the union of all attributes and all nodes that don't have any child nodes.
匹配所有属性和所有没有任何子节点的节点的联合。
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());
}
}
}
回答by nuzz
How about something like:
怎么样:
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();
}
Okay, so you weren't happy with that, how about this:
好的,所以你对此不满意,那么这个怎么样:
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();
}