xml解析

写在前面:
  【xml的解析方式有两种,即dom方式解析和sax方式解析】sax、dom是两种对xml文档进行解析的方法(没有具体实现,只是接口),所以只有它们是无法解析xml文档的;jaxp只是api,它进一步封装了sax、dom两种接口,并且提供了DomcumentBuilderFactory/DomcumentBuilder和SAXParserFactory/SAXParser(默认使用xerces解释器)。
1. dom:(Document Object Model, 即文档对象模型)是W3C组织推荐的处理XML的一种方式。
2. sax: (Simple API for XML)不是官方标准,但它是XML社区事实上的标准,几乎所有的XML解析器都支持它。
  在使用DOM解析XML文档时,需要读取整个XML文档,在内存中构建代表整个DOM树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果XML文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。
  SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。SAX采用事件处理的方式解析XML文件,利用SAX解析XML文档,涉及两个部分:解析器和事件处理器。解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。
这里写图片描述
XML解析器:Crimson、Xerces 、Aelfred2
XML解析开发包:Jaxp(jdk中)、Jdom(开源的jar包)、dom4j(开源jar包);备注:Jaxp是Javajdk本身提供的对xml文件的解析(包括了以dom、sax两种方式的解析);Jdom和dom4j是一种通过dom方式解析xml的开源工具。
  JAXP开发包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包组成。在 javax.xml.parsers 包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的 DOM 或 SAX 的解析器对象。
  javax.xml.parsers包中的DocumentBuilderFactory用于创建DOM模式的解析器对象, DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。

<?xml version="1.0" encoding="UTF-8"?>
<书架>
    <>
        <书名 name="dddd">java web就业</书名>
        <作者>码农</作者>
        <售价>40</售价> 
    </>
    <>
        <书名>C++教程</书名>
        <作者>自己</作者>
        <售价>50</售价> 
    </>
</书架>
package cn.keymobile;

import java.util.jar.Attributes;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;


/**
 * xml解析之:dom解析
 * Jaxp中包含了以dom方式解析xml的内容,Jdom和dom4j 相当是解析xml的开源工具
 * @author zhaojd
 *
 */
public class XmlParse {

    @Test
    public void jdkDomParse() throws Exception {
        //1.创建工厂
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //2.得到dom解析器
        DocumentBuilder builder = factory.newDocumentBuilder();
        //3.解析xml文档,得到代表文档的document
        Document document = builder.parse("src/book.xml");
        /**
         * 4.使用dom方式对xml文档进行CRUD
         *      ①.读取<书名>C++教程</书名>   读取到   C++教程
         *      ②.得到文档中所有标签
         *      ③.得到文档中标签属性<书名 name="xxxx">java web就业</书名>
         *      
         *      ④.添加节点  【 添加节点、挂到某个节点下】
         *      ⑤.向文档中指定位置上添加节点  <售价>10</售价>
         *      ⑥.向文档节点 添加属性 <售价>10</售价>
         *      ⑦.删除节点
         *      ⑧.更新节点
         */
        //①
        NodeList nodeList = document.getElementsByTagName("书名");
        Node node = nodeList.item(1);
        System.out.println("①:" + node.getTextContent());

        //②
        //        NodeList nodes = document.getElementsByTagName("书架");
        //        list(nodes.item(0));

        //③
        //        Node node = document.getElementsByTagName("书名").item(0);
        //        if(node.hasAttributes()){
        //            NamedNodeMap attrs = node.getAttributes();
        //            for (int i = 0; i < attrs.getLength(); i++) {
        //               Node attr = attrs.item(i);
        //               String attrName = attr.getNodeName();
        //               String attrVal = attr.getNodeValue();
        //               System.out.println("属性名称" + attrName + "; 属性值为" + attrVal);
        //            }
        //        }

        //④
        //创建节点
        //        Element priceNode = document.createElement("售价");
        //        priceNode.setTextContent("59");
        //        document.getElementsByTagName("书").item(0).appendChild(priceNode);
        //        //把更新后的内容写回到文档
        //        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        //        DOMSource source = new DOMSource(document);
        //        FileOutputStream outstream = new FileOutputStream(new File("src/outbook.xml"));
        //        StreamResult reslut = new StreamResult(outstream);
        //        transformer.transform(source, reslut);
        //        outstream.close();

        //⑤
        //        Element priveNode = document.createElement("售价");
        //        priveNode.setTextContent("88.0元");
        //        //得到参考节点
        //        Node referNode = document.getElementsByTagName("售价").item(0);
        //        //得到挂仔的节点
        //        Node pNode = document.getElementsByTagName("书").item(0);
        //        pNode.insertBefore(priveNode, referNode);
        //        
        //        Transformer transformer=TransformerFactory.newInstance().newTransformer();
        //        DOMSource source=new DOMSource(document);
        //        FileOutputStream outstream =new FileOutputStream(new File("src/outbook2.xml"));
        //        StreamResult reslut=new StreamResult(outstream);
        //        transformer.transform(source, reslut);
        //        outstream.close();     

        //⑥
        //        Element priceNode = (Element) document.getElementsByTagName("售价").item(0);
        //        priceNode.setAttribute("属性名", "属性值");
        //        Transformer transformer=TransformerFactory.newInstance().newTransformer();
        //        DOMSource source=new DOMSource(document);
        //        FileOutputStream outstream =new FileOutputStream(new File("src/outbook3.xml"));
        //        StreamResult reslut=new StreamResult(outstream);
        //        transformer.transform(source, reslut);
        //        outstream.close(); 

        //        Node node = document.getElementsByTagName("售价").item(0);
        //        node.getParentNode().removeChild(node);
        //        Transformer transformer=TransformerFactory.newInstance().newTransformer();
        //        DOMSource source=new DOMSource(document);
        //        FileOutputStream outstream =new FileOutputStream(new File("src/outbook3.xml"));
        //        StreamResult reslut=new StreamResult(outstream);
        //        transformer.transform(source, reslut);
        //        outstream.close(); 

        //⑦
        //        Element element = (Element) document.getElementsByTagName("作者").item(0);
        //        element.setTextContent("更新节点");
        //        Transformer transformer=TransformerFactory.newInstance().newTransformer();
        //        DOMSource source=new DOMSource(document);
        //        FileOutputStream outstream =new FileOutputStream(new File("src/outbook3.xml"));
        //        StreamResult reslut=new StreamResult(outstream);
        //        transformer.transform(source, reslut);
        //        outstream.close();       
    }

    /**
     * 遍历父节点下的子节点
     */
    public void list(Node node) {
        Node child;
        if (node instanceof Element) {
            System.out.println(node.getNodeName());
            NodeList childNodes = node.getChildNodes();
            for (int i = 0; i < childNodes.getLength(); i++) {
                child = childNodes.item(i);
                list(child);
            }
        }
    }

    @Test
    public void jdkSaxParse() throws Exception {
      //1.创建解析工厂
        SAXParserFactory factory=SAXParserFactory.newInstance();
        //2.得到解析器
        SAXParser sp=factory.newSAXParser();
        //3.得到读取器
        XMLReader reader=sp.getXMLReader();
        //4.设置内容处理器
        reader.setContentHandler(new TagValueHandler());
        //5.读取xml文档内容
        reader.parse("src/book.xml");
    }
}

class TagValueHandler extends DefaultHandler{
    private String currentTag;//记住当前解析器得到的是什么标签
    private int needNumber=2;//记住想获取第几个作者标签的值
    private int currentNumber;//当前解析的是第几个   
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        currentTag=qName;
        if("作者".equals(currentTag))
            currentNumber++;
    }
    public void characters(char[] ch, int start, int length)    throws SAXException {
        if("作者".equals(currentTag)&& currentNumber==needNumber){
            System.out.println(new String(ch,start,length));
        }
    }
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        currentTag=null;
    }   
}
//dom4j解析
 //读第 2 本书的信息 <书名  name="xxxx">C++教程</书名>
    @SuppressWarnings("unused")
    private static void read() throws DocumentException {
        SAXReader reader = new SAXReader();
        org.dom4j.Document document = reader.read(new File("src/book.xml"));
        Element root = document.getRootElement();
        Element book = (Element) root.elements("书").get(1);
        String value = book.element("书名").getText();
        String value2 = book.element("书名").attributeValue("name");
        System.out.println(value + ";" + value2);
    }

    //在第一本上添加一个新的售价
    @SuppressWarnings("resource")
    public void add() throws Exception {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book.xml"));
        Element book = document.getRootElement().element("书");
        book.addElement("售价").setText("111");
        //XMLWriter writer=new XMLWriter(new FileWriter("src/book.xml"));
        //XMLWriter writer=new XMLWriter(
        new OutputStreamWriter(new FileOutputStream("src/book.xml"), "UTF-8");
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("gb2312");
        XMLWriter writer =
                new XMLWriter(
                        new OutputStreamWriter(new FileOutputStream("src/book.xml"), "gb2312"),
                        format);
        writer.write(document);
        writer.close();
    }

    //在第一本书指定位置上添加一个新的售价,更改List集合   

    @SuppressWarnings({"unchecked", "rawtypes"})
    public void add2() throws Exception {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book.xml"));
        Element book = document.getRootElement().element("书");
        List list = book.elements();//[书名,作者,售价]
        Element price = DocumentHelper.createElement("售价");
        price.setText("309元");
        list.add(2, price);
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("gb2312");
        XMLWriter writer =
                new XMLWriter(
                        new OutputStreamWriter(new FileOutputStream("src/book.xml"), "gb2312"),
                        format);
        writer.write(document);
        writer.close();
    }

    //删除上面的节点
    public void delete() throws Exception {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book.xml"));
        Element price = document.getRootElement().element("书").element("售价");
        price.getParent().remove(price);
    }

    //更新节点
    public void update() throws Exception {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book.xml"));
        Element book = (Element) document.getRootElement().elements("书").get(1);
        book.element("作者").setText("张三");
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("gb2312");
        XMLWriter writer =
                new XMLWriter(
                        new OutputStreamWriter(new FileOutputStream("src/book.xml"), "gb2312"),
                        format);
        writer.write(document);
        writer.close();
    }


    //应用xpath提取xml文档的数据,需要包jaxen-1.1-beta-6.jar
    public void xpath() throws Exception {

        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book.xml"));
        String value = document.selectSingleNode("//作者").getText();//第一个值
        System.out.println(value);
    }
}

收藏阅读:
http://qingkangxu.iteye.com/blog/1838405
http://blog.csdn.net/smcwwh/article/details/7183869

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值