首先列出的是待解析的XML文档:candidate.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <people> <!-- This is Jadyer`s comment --> <person personID="P01"> <姓名 userID="U01">Tony Blair</姓名> <邮箱>[email protected]</邮箱> <地址>10 Downing Street, London, UK</地址> </person> <person personID="P02"> <姓名 userID="U02">Bill Clinton</姓名> <邮箱>[email protected]</邮箱> <地址>White House, USA</地址> </person> <person personID="P03"> <姓名 userID="U03">Tom Cruise</姓名> <邮箱>[email protected]</邮箱> <地址>57 Jumbo Street, New York, USA</地址> </person> <person personID="P04"> <姓名 userID="U04">Linda Goodman</姓名> <邮箱>[email protected]</邮箱> <地址>78 Crax Lane, London, UK</地址> </person> </people>
package com.jadyer.xml; import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Attr; import org.w3c.dom.Comment; 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; /** * 以DOM(Document Object Model)方式解析XML文档 */ public class DomParse { public static void main(String[] args) throws Exception { //Step01:获得DOM解析器工厂,该工厂用于创建具体的解析器 // 这里使用DocumentBuilderFactory的目的是为了创建与具体解析器无关的程序 // 当newInstance()被调用时,它会根据一个系统变量来决定具体使用哪一个解析器 // 又因为所有的解析器都服从于JAXP(Java API for Xml Parse)所定义的接口 // 所以无论具体使用哪一个解析器,代码都是一样的 // 所以当在不同的解析器之间进行切换时,只需更改系统变量的值,而不用更改任何代码 // 注:所使用的系统变量可以查看DocumentBuilderFactory.newInstance()的API DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); //Step02:获得具体的DOM解析器 DocumentBuilder db = dbf.newDocumentBuilder(); //Step03:解析一个XML文档,获得Document对象,即XML文档的根结点 // 注:由于使用的是DocumentBuilder.parse(File file)方法 // 注:故candidate.xml只需放在JavaProject的根目录下即可,不需要放到src下面 Document document = db.parse(new File("candidate.xml")); //获得文档的根元素节点 Element root = document.getDocumentElement(); System.out.println("*****************************************************************************************"); System.out.println("*****************************************************************************************"); System.out.println("Factory Class: " + dbf.getClass().getName()); System.out.println("Builder Class: " + db.getClass().getName()); System.out.println("Document Class: " + document.getClass().getName()); System.out.println("*****************************************************************************************"); System.out.println("*****************************************************************************************"); parseElement(root); //以DOM方式,并通过递归的手段,解析任意的XML文档,最后将其内容输出到命令行 System.out.println("\n*****************************************************************************************"); System.out.println("*****************************************************************************************"); //解析XML时要注意:节点与节点之间的空格文本,也算是根元素节点的孩子的组成部分 NodeList list11 = root.getChildNodes(); System.out.println("该XML文档的根元素节点为: " + root.getTagName()); System.out.println("根元素节点下的孩子数目为: " + list11.getLength()); System.out.println("根元素节点下的孩子名字为: 如下所示"); for(int i=0; i<list11.getLength(); i++){ System.out.println(" " + list11.item(i).getNodeName()); } System.out.println("========================================================================================="); //获得所有的标签名为'PERSON'的节点 NodeList list22 = document.getElementsByTagName("person"); for(int i=0; i<list22.getLength(); i++){ Element element = (Element)list22.item(i); NamedNodeMap nnm = element.getAttributes(); System.out.print(nnm.item(0).getNodeName()); System.out.print("="); System.out.println(nnm.item(0).getNodeValue()); String content = element.getElementsByTagName("姓名").item(0).getFirstChild().getNodeValue(); String contentAttr = element.getElementsByTagName("姓名").item(0).getAttributes().item(0).getNodeName(); String contentvalue = element.getElementsByTagName("姓名").item(0).getAttributes().item(0).getNodeValue(); System.out.println(contentAttr + "=" + contentvalue); System.out.println("姓名: " + content); content = element.getElementsByTagName("邮箱").item(0).getFirstChild().getNodeValue(); System.out.println("邮箱: " + content); content = element.getElementsByTagName("地址").item(0).getFirstChild().getNodeValue(); System.out.println("地址: " + content); System.out.println("========================================================================================="); } } /** * 以DOM方式,并通过递归的手段,解析任意的XML文档,最后将其内容输出到命令行 */ private static void parseElement(Element element) { String tagName = element.getNodeName(); NodeList children = element.getChildNodes(); System.out.print("<" + tagName); //element元素的所有属性所构成的NamedNodeMap对象,需要对其进行判断 NamedNodeMap map = element.getAttributes(); if(null != map){ //如果该元素存在属性 for(int i=0; i<map.getLength(); i++){ Attr attr = (Attr) map.item(i); //获得该元素的每一个属性 System.out.print(" " + attr.getName() + "=\"" + attr.getValue() + "\""); } } System.out.print(">"); for(int i=0; i<children.getLength(); i++){ Node node = children.item(i); short nodeType = node.getNodeType(); //获得节点的类型 if(Node.ELEMENT_NODE == nodeType){ parseElement((Element)node); //是元素,继续递归 }else if(Node.TEXT_NODE == nodeType){ System.out.print(node.getNodeValue()); //递归出口 }else if(Node.COMMENT_NODE == nodeType){ System.out.print("<!--"); Comment comment = (Comment) node; System.out.print(comment.getData()); //注释的内容 System.out.print("-->"); } } System.out.print("</" + tagName + ">"); } }
下面是以SAX方式解析XML的演示:SaxParse.java
package com.jadyer.xml; import java.io.File; import java.util.Stack; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * 以SAX(Simple APIs for XML)方式解析XML文档 * @see DOM解析XML时,会将XML文档加载到内存,然后通过随机的方式访问内存中的DOM树 * @see SAX是基于事件而且是顺序执行的,一旦经过了某元素,我们就没有办法再去访问它了 * @see SAX不必事先将整个XML文档加载到内存当中,因此它占据内存要比DOM小 * @see 对于大型的XML文档来说,通常会使用SAX而不是DOM进行解析 */ public class SaxParse { public static void main(String[] args) throws Exception { //Step01:获得SAX解析器工厂实例 SAXParserFactory factory = SAXParserFactory.newInstance(); //Step02:获得SAX解析器实例 SAXParser parser = factory.newSAXParser(); //Step03:开始解析 parser.parse(new File("candidate.xml"), new MyHandler11()); parser.parse(new File("candidate.xml"), new MyHandler22()); } } /** * * MyHandler11 * @see org.xml.sax.helpers.DefaultHandler类的处理方法 * @see 项目 处理方法 * @see 文档的开始 startDocument() * @see <people> startElement() * @see "春运订票" characters() * @see </people> endElement() * @see 文档的开始 endDocument() */ class MyHandler11 extends DefaultHandler { @Override public void startDocument() throws SAXException { System.out.println("====================================================="); System.out.println("Document_start"); } @Override public void endDocument() throws SAXException { System.out.println("Document_end"); System.out.println("====================================================="); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("Element_Start"); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("Element_End"); } } class MyHandler22 extends DefaultHandler { private Stack<String> stack = new Stack<String>(); private String name; private String email; private String address; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { stack.push(qName); //qName表示标签的名字。即<person personID="P01">中的person for(int i = 0; i<attributes.getLength(); i++){ String attrName = attributes.getQName(i); //获得第i个属性的名字。即personID String attrValue = attributes.getValue(i); //获得第i个属性的值。即P01 System.out.println(attrName + "=" + attrValue); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { String tag = stack.peek(); if("姓名".equals(tag)){ name = new String(ch, start, length); }else if("邮箱".equals(tag)){ email = new String(ch, start, length); }else if("地址".equals(tag)){ address = new String(ch, start, length); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { stack.pop(); //表示该元素已经解析完毕,需要从栈中弹出 if("person".equals(qName)){ System.out.println("姓名: " + name); System.out.println("邮箱: " + email); System.out.println("地址: " + address); System.out.println("====================================================="); } } }