精华帖 (0) :: 良好帖 (2) :: 新手帖 (2) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-02
最后修改:2009-06-02
以 DOM 方式解析XML文档,示例如下(标有详细注释)
package Test_DOM; import java.io.File; import java.io.IOException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class Test { public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { DocumentBuilderFactory builderFactory = DocumentBuilderFactory .newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); /* * builder.parse()方法将给定文件的内容解析为一个 XML 文档, 并且返回一个新的 DOM Document对象。 */ Document document = builder.parse(new File("books.xml")); //打印document节点 printNode(document,0); //获取文档的根元素,赋值给rootElement变量 Element rootElement = document.getDocumentElement(); //获取元素的count属性 int countOfBooks = Integer.parseInt(rootElement.getAttribute("count")); System.out.println("There are "+countOfBooks+" books , they are "); //获取rootElement的所有子节点(不包括属性节点),返回一个NodeList对象 NodeList childNodes = rootElement.getChildNodes(); for(int i = 0;i < childNodes.getLength();i++){ //获取childNodes的第i个节点 Node childNode = childNodes.item(i); //判断childNode是不是一个元素节点,并且它的 nodeName 值为book if(childNode.getNodeType() == Node.ELEMENT_NODE && childNode.getNodeName().equals("book")){ //若是,则获取childNode的所有子节点(不包括属性节点),返回一个NodeList对象 NodeList childNodes_2 = childNode.getChildNodes(); for(int j = 0;j < childNodes_2.getLength();j++){ //获取childNodes_2的第j个节点 Node childNode_2 = childNodes_2.item(j); //判断childNode_2是不是一个元素节点,并且它的 nodeName 值为name if(childNode_2.getNodeType() == Node.ELEMENT_NODE && childNode_2.getNodeName().equals("name")){ //若是,则获取childNode_2的所有子节点(不包括属性节点),返回一个NodeList对象 NodeList childNodes_3 = childNode_2.getChildNodes(); for(int k = 0;k < childNodes_3.getLength();k++){ //获取childNodes_3的第k个节点 Node childNode_3 = childNodes_3.item(k); //判断childNodes_3是不是一个文本节点 if(childNode_3.getNodeType() == Node.TEXT_NODE){ //若是,则打印输出这个文本节点的nodeValue System.out.println(" <<"+childNode_3.getNodeValue()+">>"); } } } } } } } /* * 打印 DOM 节点 * 输出格式为: * nodeType(nodeName,nodeValue) * "ATTRIBUTE"(attributeName=attributeValue) * ... * childNodeType[childNodeName,childNodeValue] * ... */ public static void printNode(Node node,int count) { if (node != null) { String tmp = ""; for(int i = 0 ; i < count ; i++) tmp += " "; //获取node节点的节点类型,赋值给nodeType变量 int nodeType = node.getNodeType(); switch (nodeType) { case Node.ATTRIBUTE_NODE: tmp += "ATTRIBUTE";break; case Node.CDATA_SECTION_NODE: tmp += "CDATA_SECTION";break; case Node.COMMENT_NODE:tmp += "COMMENT";break; case Node.DOCUMENT_FRAGMENT_NODE:tmp += "DOCUMENT_FRAGMENT";break; case Node.DOCUMENT_NODE:tmp += "DOCUMENT";break; case Node.DOCUMENT_TYPE_NODE:tmp += "DOCUMENT_TYPE";break; case Node.ELEMENT_NODE:tmp += "ELEMENT";break; case Node.ENTITY_NODE:tmp += "ENTITY";break; case Node.ENTITY_REFERENCE_NODE:tmp += "ENTITY_REFERENCE";break; case Node.NOTATION_NODE:tmp += "NOTATION";break; case Node.PROCESSING_INSTRUCTION_NODE:tmp += "PROCESSING_INSTRUCTION";break; case Node.TEXT_NODE:tmp += "TEXT";break; default:return;//invalid node type. } System.out.println(tmp+" ("+node.getNodeName()+","+node.getNodeValue()+")"); /* * node.getAttributes()方法返回 * 包含node节点的属性的 NamedNodeMap(如果它是 Element) */ NamedNodeMap attrs = node.getAttributes(); if(attrs != null) for(int i = 0 ; i < attrs.getLength() ; i++){ printNode(attrs.item(i),count+1); } /* * node.getChildNodes()方法返回 * 包含node节点的所有子节点的 NodeList。 */ NodeList childNodes = node.getChildNodes(); for(int i = 0 ; i < childNodes.getLength() ; i++){ printNode(childNodes.item(i),count+1); } } } }
books.xml 的内容如下:
<?xml version="1.0" encoding="GB2312"?> <books count="3" xmlns="http://test.org/books"> <!--books's comment--> <book id="1"> <name>Thinking in JAVA</name> </book> <book id="2"> <name>Core JAVA2</name> </book> <book id="3"> <name>C++ primer</name> </book> </books> 运行结果如下: DOCUMENT (#document,null)
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-06-02
最后修改:2009-06-02
java的DOM解析实在有点无里头
比如这个 DocumentBuilderFactory builderFactory = DocumentBuilderFactory .newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); 这些语义不清楚的Factory和builder就是让语句看得更复杂。 |
|
返回顶楼 | |
发表时间:2009-06-02
ray_linn 写道 java的DOM解析实在有点无里头
比如这个 DocumentBuilderFactory builderFactory = DocumentBuilderFactory .newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); 这些语义不清楚的Factory和builder就是让语句看得更复杂。 呵呵 所以更多的人喜欢用jdom 和 dom4j 但是理解JAVA DOM里的一些概念还是必要的 毕竟它是W3C DOM的JAVA标准实现, 而且大部分开源DOM解析器,都支持与JAVA 标准DOM之间的转换, 至于factory和builder我也觉得敲起来有点 麻烦,但是语义还是比较明确的 就是用工厂类 创建一个文档(Document)构造器,至于为什么 这么麻烦,可能是为了让DOM API更容易扩展。 |
|
返回顶楼 | |
发表时间:2009-06-03
XPathFactory xpathFactory = XPathFactory.newInstance(); XPath xpath = xpathFactory.newXPath(); /* * 如果这个XPath表达式会被求值多次最好用下面这种求值方式 * 先编译XPath表达式 * XPathExpression xpathExpr = xpath.compile("//book/name/text()"); * NodeList nodeList = (NodeList)xpathExpr.evaluate(document, XPathConstants.NODESET); */ NodeList nodeList = (NodeList)xpath.evaluate("//book/name/text()", doc, XPathConstants.NODESET); if(nodeList != null){ for(int i = 0; i < nodeList.getLength();i++){ System.out.println(" <<"+nodeList.item(i).getNodeValue()+">>"); } } 这段用XPath来查找所有书名的代码比上面的代码简单多了 (实际上用DOM解析xml是最复杂的,有很多途径可以 轻松解析XML,比如用JDOM。。) 输出结果为: <<Thinking in JAVA>> <<Core JAVA2>> <<C++ primer>> |
|
返回顶楼 | |
浏览 15185 次