简单javaXML读取——DOM、SAX

简单程序时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 的属性的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值