简单javaXML读取——DOM、SAX

来源:互联网 发布:java自学书 编辑:程序博客网 时间:2024/06/09 23:49

简单程序时xml相较数据库要更为简单直接,一个文本文件就足够记录一些简单的条目了。同时作为配置文件选择xml也是极好的。java操作xml的技术应该有不少,在这里只谈DOM、SAX,两者应用都很广泛,在不同情况下都有各自优点。

对比DOM和SAX,可以简单理解为:
DOM是直接把xml全部读取放到内存中然后操作,并包含一整套方法完成对xml文档的操作;
SAX要更为简单,只能读取xml文件,一边读源文件一边触发事件,程序员需要在事件中加入想要的功能,因而程序员能更大程度控制处理xml文档的资源开销。

这么看来如果只是要去xml文档中查数据的话SAX是比较适合的,如果要增删查改xml的内容,似乎应该用DOM,功能丰富,只不过要占用多一些内存。

先看看SAX,直接给完整代码

import java.io.File;import javax.xml.parsers.*;import org.xml.sax.helpers.*;import org.xml.sax.*;public class saxTest extends DefaultHandler{private String ElementName;public saxTest(){    this.ElementName="";}public void startDocument(){}public void startElement(String uri,String localName,String qName,Attributes attributes){    this.ElementName=qName;    if(qName.equals("ElementName1")){        System.out.println(attributes.getValue("id"));//获取标签的属性,既可以用属性名,也可以用下标        System.out.println(attributes.getValue(0));    }}public void characters(char[] ch,int start,int length){    String str=new String(ch,start,length);    System.out.println(str);}public void endElement(String uri,String localName,String qName){}public void endDocument(){}public static void main(String[] args)throws Exception{    SAXParserFactory factory=SAXParserFactory.newInstance();    SAXParser parser=factory.newSAXParser();    parser.parse(new File("xmlsrc.xml"),new saxTest());}}

相应的xml文档

<?xml version="1.0" encoding="gb2312"?><ElementName1 id="1">abcdefg</ElementName1>

运行结果应该是
1
1
abcdefg

比较让人疑惑的是除了main以外还有那么多方法都在哪里调用的?
main方法中有一句

parser.parse(new File("xmlsrc.xml"),new saxTest());

传入的参数是xml文档路径,一个继承DefaultHandler的saxTest实例

parser.parse()这个方法就会触发SAX解析器开始解析xml文档,当遇到文档中的标签时就会触发事件。比如
读取到
<?xml version="1.0" encoding="gb2312"?>触发startDocument()事件
<ElementName1 id="1">触发startElement()事件
abcdefg 触发characters()事件
</ElementName1>触发endElement()事件
。。。。。。

程序员的工作就是在这些事件中加入自己的代码

至于DOM,它的背景这里就不赘述了,给一个百度百科的链接

DOM操作xml文件会用Document、Node、NodeList、Element这几个类的实例来表示xml文件中的各个节点
Document:表示整个xml文档
Node、Element:表示文档中的节点,这两个类的实例是可以相互强制转换的
NodeList:elementInstance.getChildNodes()返回NodeList实例,NodeListInstance.item(i)就可以获得第i个子节点

直接来代码,粘贴到eclipse中会自动提示需要引用的包

public static void main(String[] args){    try {                  DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();                dbf.setIgnoringElementContentWhitespace(true);                Document doc = dbf.newDocumentBuilder().parse(“xmlsrc.xml");     // 以上获取一个Document实例,没什么可变的                Element root = doc.getDocumentElement();//根节点                NodeList nodes_level1 = root.getChildNodes();//获得根节点下所有子节点                FindAll(nodes_level1);            } catch (ParserConfigurationException e) {              System.out.println(e.getMessage());            } catch (FileNotFoundException e) {                  e.printStackTrace();              } catch (SAXException e) {                  e.printStackTrace();              } catch (IOException e) {                  e.printStackTrace();              } }private void FindAll(NodeList nodes_level1){//获得一个NodeList后,获取其子节点有关数据,但子节点可能还包含二级节点,在以下for循环最后使用了迭代,这样就能遍历所有节点了    for(int i=0; i<nodes_level1.getLength(); i++){            Node node_level2 = nodes_level1.item(i);            if(node_level2.getNodeType() == Node.ELEMENT_NODE){                try{                System.out.println(node_level2.getAttributes().getNamedItem("name").getNodeValue());//获得指定属性值            }catch(Exception e){}            System.out.println(               node_level2.getTextContent().trim());//获得标签之间的值            System.out.println(                node_level2.getNodeName());//获得标签名            System.out.println(               node_level2.getAttributes().item(0));//获得标签包含的属性            if(!(node_level2.getChildNodes() == null)){                FindAll(node_level2.getChildNodes());            }            }}

还有一些 DOM 常用的方法:

Node.getFirstChild() 、Node.getLastChild():返回给定 Node 的第一个和最后一个子节点。

Node.getNextSibling() 、 Node.getPreviousSibling():返回给定 Node 的下一个和上一个同级节点。

Element.getAttribute(String attrName):对于给定的 Element,返回名为 attrName 的属性的值。

0 0