首页 > 编程学习 > XML编程(CRUD)

XML编程(CRUD)

发布时间:2022/1/17 12:29:11

XML解析技术概述

  • XML解析方式分为两种:dom和sax
    • dom:(Document Object Model, 即文档对象模型) 是 W3C 组织推荐的处理 XML 的一种方式。
    • sax: (Simple API for XML) 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。
  • XML解析器

Crimson、Xerces 、Aelfred2

  • XML解析开发包

Jaxp、Jdom、dom4j

JAXP

  • JAXP 开发包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包组成
  • 在 javax.xml.parsers 包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的 DOM 或 SAX
    的解析器对象。

使用JAXP进行DOM解析

  • javax.xml.parsers 包中的DocumentBuilderFactory用于创建DOM模式的解析器对象 , DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法 ,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。

获得JAXP中的DOM解析器

  • 调用 DocumentBuilderFactory.newInstance() 方法得到创建 DOM 解析器的工厂。
  • 调用工厂对象的 newDocumentBuilder方法得到 DOM 解析器对象。
  • 调用 DOM 解析器对象的 parse() 方法解析 XML 文档,得到代表整个文档的 Document
    对象,进行可以利用DOM特性对整个XML文档进行操作了。

DOM编程

  • DOM模型(document object model)
    • DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。
    • 在dom中,节点之间关系如下:
      • 位于一个节点之上的节点是该节点的父节点(parent)
      • 一个节点之下的节点是该节点的子节点(children)
      • 同一层次,具有相同父节点的节点是兄弟节点(sibling)
      • 一个节点的下一个层次的节点集合是节点后代(descendant)
      • 父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)

Node对象

  • Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。(查看API文档)
  • Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。

DOM方式解析XML文件

  • DOM解析编程
    • 遍历所有节点
    • 查找某一个节点
    • 删除结点
    • 更新结点
    • 添加节点

DOM编程练习

book1.xml

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<书架>
    < name="yyyyyyy">
        <售价>109</售价>
        <售价>39元</售价>
        <书名>Java就业培训教程</书名>
        <作者>张孝祥</作者>


    </>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>

</书架>
  • 遍历所有节点
public class Demo1 {

    /**使用jaxp操作xml文档
     * @param args
     * @throws ParserConfigurationException 
     * @throws IOException 
     * @throws SAXException 
     */
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {

        //1.获取工厂
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();


        //2.产生解析器
        DocumentBuilder builder = factory.newDocumentBuilder();

        //3.解析xml文档,得到代表文档的document
        Document document = builder.parse(new File("src/book1.xml"));

        //遍历
        list(document);
    }
    //遍历
    public static void list(Node node){

        if(node.getNodeType()==Node.ELEMENT_NODE){
            System.out.println(node.getNodeName());
        }

        NodeList list = node.getChildNodes();
        for(int i=0;i<list.getLength();i++){
            Node child = list.item(i);
            list(child);
        }
    }
}

这里写图片描述

  • 查找某一个节点
//得到售价结点的值
    @Test
    public void read() throws Exception{

        //1.获取工厂
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(new File("src/book.xml"));

        NodeList list = document.getElementsByTagName("售价");
        Node price = list.item(0);

        String value = price.getTextContent();
        System.out.println(value);
    }

这里写图片描述

  • 添加节点

    //向指定节点中增加孩子节点(售价节点)
    @Test
    public void add() throws Exception{
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder  builder = factory.newDocumentBuilder();
        Document document = builder.parse(new File("src/book1.xml"));

        //创建需要增加的节点
        Node price = document.createElement("售价");
        price.setTextContent("59元");

        //得到需要增加的节点的父亲
        Node parent = document.getElementsByTagName("书").item(0);

        //把需要增加的节点挂到父结点上
        parent.appendChild(price);

        //把内存中的document写到xml文档
        TransformerFactory tf = TransformerFactory.newInstance();
        //得到转换器
        Transformer ts = tf.newTransformer();
        ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));

    }

执行后

<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
    < name="yyyyyyy">
        <售价>109</售价>
        <售价>39元</售价>
        <书名>Java就业培训教程</书名>
        <作者>张孝祥</作者>


    <售价>59元</售价></>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>

</书架>
//向指定位置上插入售价节点
    @Test
    public void add2() throws Exception{
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder  builder = factory.newDocumentBuilder();
        Document document = builder.parse(new File("src/book1.xml"));

        Node node = document.createElement("售价");
        node.setTextContent("39元");

        Node parent = document.getElementsByTagName("书").item(0);
        parent.insertBefore(node, document.getElementsByTagName("书名").item(0));

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer ts = tf.newTransformer();
        ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
    }

执行后

<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
    < name="yyyyyyy">
        <售价>109</售价>
        <售价>39元</售价>
        <售价>39元</售价><书名>Java就业培训教程</书名>
        <作者>张孝祥</作者>


    <售价>59元</售价></>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>

</书架>
  • 更新结点
//修改结点的值:<售价>109</售价>改为111
    @Test
    public  void update() throws Exception{

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder  builder = factory.newDocumentBuilder();
        Document document = builder.parse(new File("src/book1.xml"));

        Node price = document.getElementsByTagName("售价").item(0);
        price.setTextContent("111");


        //把内存中的document写到xml文档
        TransformerFactory tf = TransformerFactory.newInstance();
        //得到转换器
        Transformer ts = tf.newTransformer();
        ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
    }

执行后

<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
    < name="yyyyyyy">
        <售价>111</售价>
        <售价>39元</售价>
        <售价>39元</售价><书名>Java就业培训教程</书名>
        <作者>张孝祥</作者>


    <售价>59元</售价></>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>

</书架>
  • 删除结点
//删除xml文档的售价结点
    @Test
    public void delete() throws Exception{
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder  builder = factory.newDocumentBuilder();
        Document document = builder.parse(new File("src/book1.xml"));

        Node node = document.getElementsByTagName("售价").item(2);
        node.getParentNode().removeChild(node);

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer ts = tf.newTransformer();
        ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
    }

执行后

<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
    < name="yyyyyyy">
        <售价>111</售价>
        <售价>39元</售价>
        <书名>Java就业培训教程</书名>
        <作者>张孝祥</作者>


    <售价>59元</售价></>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>

</书架>
  • 操作xml文档属性
    //操作xml文档属性
    @Test
    public void updateAttribute() throws Exception{
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder  builder = factory.newDocumentBuilder();
        Document document = builder.parse(new File("src/book1.xml"));


        //操作xml文档的元素时,一般都把元素当作node对象,但是程序员如果发现node不好使时,就应把node强转成相应类型
        Node node  = document.getElementsByTagName("书").item(0);
        Element book = null;
        if(node.getNodeType()==Node.ELEMENT_NODE){  //在作结点转换之前,最好先判断结点类型
            book  = (Element)node;
        }

        book.setAttribute("name", "yyyyyyy");
        book.setAttribute("password", "123");


        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer ts = tf.newTransformer();
        ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
    }

执行后

<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
    < name="yyyyyyy" password="123">
        <售价>111</售价>
        <售价>39元</售价>
        <售价>39元</售价><书名>Java就业培训教程</书名>
        <作者>张孝祥</作者>


    <售价>59元</售价></>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>

</书架>
//移除xml文档属性
    @Test
    public void updateAttribute() throws Exception{
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder  builder = factory.newDocumentBuilder();
        Document document = builder.parse(new File("src/book1.xml"));


        //操作xml文档的元素时,一般都把元素当作node对象,但是程序员如果发现node不好使时,就应把node强转成相应类型
        Node node  = document.getElementsByTagName("书").item(0);
        Element book = null;
        if(node.getNodeType()==Node.ELEMENT_NODE){  //在作结点转换之前,最好先判断结点类型
            book  = (Element)node;
        }

//      book.setAttribute("name", "yyyyyyy");
//      book.setAttribute("password", "123");
        book.removeAttribute("password");

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer ts = tf.newTransformer();
        ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
    }

执行后

<?xml version="1.0" encoding="utf-8" standalone="no"?><书架>
    < name="yyyyyyy">
        <售价>111</售价>
        <售价>39元</售价>
        <售价>39元</售价><书名>Java就业培训教程</书名>
        <作者>张孝祥</作者>


    <售价>59元</售价></>
    <>
        <书名>JavaScript网页开发</书名>
        <作者>张孝祥</作者>
        <售价>28.00元</售价>
    </>

</书架>
  • 删除整个XML文档
//删除整个xml文档
        @Test
        public void delete2() throws Exception{
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder  builder = factory.newDocumentBuilder();
            Document document = builder.parse(new File("src/book1.xml"));

            //得到要删除的结点
            Element e = (Element) document.getElementsByTagName("售价").item(0);
            e.getParentNode().getParentNode().getParentNode().removeChild(e.getParentNode().getParentNode());

            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer ts = tf.newTransformer();
            ts.transform(new DOMSource(document), new StreamResult(new File("src/book1.xml")));
        }

执行后

<?xml version="1.0" encoding="utf-8" standalone="no"?>

更新XML文档

  • javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。
  • Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过:

    • javax.xml.transform.dom.DOMSource类来关联要转换的document对象,
    • javax.xml.transform.stream.StreamResult 对象来表示数据的目的地。
  • Transformer对象通过TransformerFactory获得。

SAX解析

  • 在使用 DOM 解析 XML 文档时,需要读取整个 XML 文档,在内存中构架代表整个 DOM
    树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果 XML
    文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。
  • SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。
  • SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:
    • 解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
    • 解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
    • 事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。

这里写图片描述

  • 阅读ContentHandler API文档,常用方法:startElement、endElement、characters

SAX方式解析XML文档

  • 使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
  • 通过SAX解析工厂得到解析器对象
SAXParser sp = spf.newSAXParser();
  • 通过解析器对象得到一个XML的读取器
XMLReader xmlReader = sp.getXMLReader();
  • 设置读取器的事件处理器
xmlReader.setContentHandler(new BookParserHandler());
  • 解析xml文件
xmlReader.parse("book.xml");

SAX解析编程

book.xml

<?xml version="1.0" encoding="UTF-8"?>

<书架> 
  < name="yyyyyyy"> 
    <售价>209元</售价>  
    <售价>19元</售价>
    <书名>Java就业培训教程</书名>  
    <作者>张孝祥</作者>  
    <售价>19元</售价>  
    <售价>19元</售价> 
  </>  
  <> 
    <书名>JavaScript网页开发</书名>  
    <作者>张孝祥</作者>  
    <售价>28.00元</售价> 
  </> 
</书架>
public class Demo1 {

    /**
     *sax方式解析book1.xml文件
     * @throws SAXException 
     * @throws ParserConfigurationException 
     * @throws IOException 
     */
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {


        //1.创建工厂
        SAXParserFactory factory = SAXParserFactory.newInstance();

        //2.用工厂创建解析器
        SAXParser sp = factory.newSAXParser();

        //3.利用解析器得到reader
        XMLReader reader = sp.getXMLReader();

        //4、在解析xml文档之前,设置好事件处理器
        reader.setContentHandler(new MyContentHandler());

        //4.利用reader读取 xml文档
        reader.parse("src/book1.xml");
    }
}


//得到xml文档内容的事件处理器
class MyContentHandler implements ContentHandler{

    public void startElement(String uri, String localName, String name,
            Attributes atts) throws SAXException {

        System.out.println("当前解析到了:" + name + ",这个标签是开始标签");
        for(int i=0;i<atts.getLength();i++){
            String attname = atts.getQName(i);
            String attvalue = atts.getValue(i);

            System.out.println(attname + "=" + attvalue);
        }


    }

    public void endElement(String uri, String localName, String name)
    throws SAXException {

        System.out.println("当前解析到了:" + name + ",这个标签是结束标签");

    }

    public void characters(char[] ch, int start, int length)
            throws SAXException {

        System.out.println("当前解析到了内容:" + new String(ch,start,length));
    }

    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub

    }



    public void endPrefixMapping(String prefix) throws SAXException {
        // TODO Auto-generated method stub

    }

    public void ignorableWhitespace(char[] ch, int start, int length)
            throws SAXException {
        // TODO Auto-generated method stub

    }

    public void processingInstruction(String target, String data)
            throws SAXException {
        // TODO Auto-generated method stub

    }

    public void setDocumentLocator(Locator locator) {
        // TODO Auto-generated method stub

    }

    public void skippedEntity(String name) throws SAXException {
        // TODO Auto-generated method stub

    }

    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub

    }



    public void startPrefixMapping(String prefix, String uri)
            throws SAXException {
        // TODO Auto-generated method stub

    }



}

运行结果:

当前解析到了:书架,这个标签是开始标签
当前解析到了内容: 

当前解析到了:书,这个标签是开始标签
name=yyyyyyy
当前解析到了内容: 

当前解析到了:售价,这个标签是开始标签
当前解析到了内容:209元
当前解析到了:售价,这个标签是结束标签
当前解析到了内容:  

当前解析到了:售价,这个标签是开始标签
当前解析到了内容:19元
当前解析到了:售价,这个标签是结束标签
当前解析到了内容:

当前解析到了:书名,这个标签是开始标签
当前解析到了内容:Java就业培训教程
当前解析到了:书名,这个标签是结束标签
当前解析到了内容:  

当前解析到了:作者,这个标签是开始标签
当前解析到了内容:张孝祥
当前解析到了:作者,这个标签是结束标签
当前解析到了内容:  

当前解析到了:售价,这个标签是开始标签
当前解析到了内容:19元
当前解析到了:售价,这个标签是结束标签
当前解析到了内容:  

当前解析到了:售价,这个标签是开始标签
当前解析到了内容:19元
当前解析到了:售价,这个标签是结束标签
当前解析到了内容: 

当前解析到了:书,这个标签是结束标签
当前解析到了内容:  

当前解析到了:书,这个标签是开始标签
当前解析到了内容: 

当前解析到了:书名,这个标签是开始标签
当前解析到了内容:JavaScript网页开发
当前解析到了:书名,这个标签是结束标签
当前解析到了内容:  

当前解析到了:作者,这个标签是开始标签
当前解析到了内容:张孝祥
当前解析到了:作者,这个标签是结束标签
当前解析到了内容:  

当前解析到了:售价,这个标签是开始标签
当前解析到了内容:28.00元
当前解析到了:售价,这个标签是结束标签
当前解析到了内容: 

当前解析到了:书,这个标签是结束标签
当前解析到了内容: 

当前解析到了:书架,这个标签是结束标签
public class Demo1 {

    /**
     *sax方式解析book1.xml文件
     * @throws SAXException 
     * @throws ParserConfigurationException 
     * @throws IOException 
     */
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {


        //1.创建工厂
        SAXParserFactory factory = SAXParserFactory.newInstance();

        //2.用工厂创建解析器
        SAXParser sp = factory.newSAXParser();

        //3.利用解析器得到reader
        XMLReader reader = sp.getXMLReader();

        //4、在解析xml文档之前,设置好事件处理器
        reader.setContentHandler(new MyContentHandler2());

        //4.利用reader读取 xml文档
        reader.parse("src/book1.xml");
    }
}
//用于获取第一个售价节点的值:<售价>109</售价>
class MyContentHandler2 extends DefaultHandler{

    private boolean isOk = false;
    private int index = 1;
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        if(isOk==true && index==1){
            System.out.println(new String(ch,start,length));
        }
    }

    @Override
    public void startElement(String uri, String localName, String name,
            Attributes attributes) throws SAXException {
        if(name.equals("售价")){
            isOk = true;
        }
    }

    @Override
    public void endElement(String uri, String localName, String name)
            throws SAXException {
        if(name.equals("售价")){
            isOk = false;
            index++;
        }
    }





}

修改book.xml

<?xml version="1.0" encoding="UTF-8"?>

<书架> 
  < name="yyyyyyy"> 
    <售价>209元</售价>  
    <售价>19元</售价>
    <书名>Java就业培训教程</书名>  
    <作者>张孝祥</作者>  
    <售价>19元</售价>  
    <售价>19元</售价> 
  </>  
  <> 
    <书名>JavaScript网页开发</书名>  
    <作者>黎活明</作者>  
    <售价>28.00元</售价> 
  </> 
</书架>
public class Demo1 {

    /**
     *sax方式解析book1.xml文件
     * @throws SAXException 
     * @throws ParserConfigurationException 
     * @throws IOException 
     */
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {


        //1.创建工厂
        SAXParserFactory factory = SAXParserFactory.newInstance();

        //2.用工厂创建解析器
        SAXParser sp = factory.newSAXParser();

        //3.利用解析器得到reader
        XMLReader reader = sp.getXMLReader();

        //4、在解析xml文档之前,设置好事件处理器
        reader.setContentHandler(new TagValueHandler());

        //4.利用reader读取 xml文档
        reader.parse("src/book1.xml");
    }
}
//获取指定标签的值
class TagValueHandler extends DefaultHandler{

    private String currentTag;  //记住当前生命标签
    private int needNumber = 2; //记住想要获取第几个标签
    private int currentNumber;  //当前解析到的是第几个标签


    @Override
    public void startElement(String uri, String localName, String name,
            Attributes attributes) throws SAXException {
        currentTag = name;
        if(currentTag.equals("作者")){
            currentNumber ++;
        }
    }
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        if("作者".equals(currentTag) && currentNumber == needNumber){
            System.out.println(new String(ch,start,length));
        }
    }
    @Override
    public void endElement(String uri, String localName, String name)
            throws SAXException {
        currentTag = null;
    }


}

这里写图片描述

sax解析案例(javabean封装xml文档数据)

<?xml version="1.0" encoding="UTF-8"?>

<书架> 
  < name="yyyyyyy"> 
    <书名>Java就业培训教程</书名>  
    <作者>张孝祥</作者>  
    <售价>19元</售价>   
  </>  
  <> 
    <书名>JavaScript网页开发</书名>  
    <作者>黎活明</作者>  
    <售价>28.00元</售价> 
  </> 
</书架>

创建一个book类

public class Book {

    private String name;
    private String author;
    private String price;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
    @Override
    public String toString() {
        return "Book [name=" + name + ", author=" + author + ", price=" + price + "]";
    }



}
public class Demo2 {
    /**
     *sax方式解析book1.xml文件
     * @throws SAXException 
     * @throws ParserConfigurationException 
     * @throws IOException 
     */
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {


        //1.创建工厂
        SAXParserFactory factory = SAXParserFactory.newInstance();

        //2.用工厂创建解析器
        SAXParser sp = factory.newSAXParser();

        //3.利用解析器得到reader
        XMLReader reader = sp.getXMLReader();

        //4、在解析xml文档之前,设置好事件处理器
        BeanListHandler handler = new BeanListHandler();

        reader.setContentHandler(handler);

        //4.利用reader读取 xml文档
        reader.parse("src/book1.xml");

        List<Book> list = handler.getList();
        for(Book book : list){
            System.out.println(book);
        }
    }
}

//把xml文档中的每一本书封装到一个book对象,并把对个book对象放在一个list集合中返回
class BeanListHandler extends DefaultHandler{

    private List list = new ArrayList();
    private String currentTag;
    private Book book;
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // TODO Auto-generated method stub
        currentTag = qName;
        if("书".equals(currentTag)){
            book = new Book();
        }

    }


    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // TODO Auto-generated method stub
        if("书名".equals(currentTag)){
            String name = new String(ch,start,length);
            book.setName(name);
        }
        if("作者".equals(currentTag)){
            String author = new String(ch,start,length);
            book.setAuthor(author);
        }
        if("售价".equals(currentTag)){
            String price = new String(ch, start, length);
            book.setPrice(price);
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        // TODO Auto-generated method stub
        if(qName.equals("书")){
            list.add(book);
            book = null;
        }
        currentTag = null;//不加上会报java.lang.NullPointerException
    }


    public List getList() {
        return list;
    }


}

这里写图片描述

DOM4J解析XML文档

  • Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。

  • Dom4j是一个非常优秀的Java XML
    API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。

  • 使用Dom4j开发,需下载dom4j相应的jar文件。

Document对象

DOM4j中,获得Document对象的方式有三种:

1.读取XML文件,获得document对象

 SAXReader reader = new SAXReader();
 Document   document = reader.read(new File("input.xml"));

2.解析XML形式的文本,得到document对象.

 String text = "<members></members>";
 Document document = DocumentHelper.parseText(text);

3.主动创建document对象.

Document document = DocumentHelper.createDocument();          
//创建根节点
Element root = document.addElement("members");

节点对象

1.获取文档的根节点.

   Element root = document.getRootElement();

2.取得某个节点的子节点.

Element element=node.element("书名");

3.取得节点的文字

      String text=node.getText();

4.取得某节点下所有名为“member”的子节点,并进行遍历.

 List nodes = rootElm.elements("member")
 for (Iterator it = nodes.iterator(); it.hasNext();) {
      Element elm = (Element) it.next();
      // do something
  }

5.对某节点下的所有子节点进行遍历.

  for(Iterator it=root.elementIterator();it.hasNext();){
       Element element = (Element) it.next();
       // do something
   }

6.在某节点下添加子节点.

Element ageElm = newMemberElm.addElement("age");

7.设置节点文字.

 element.setText("29");

8.删除某节点.

//childElm是待删除的节点,parentElm是其父节点
 parentElm.remove(childElm);

9.添加一个CDATA节点.

Element contentElm = infoElm.addElement("content");
contentElm.addCDATA(diary.getContent());

节点对象属性 

1.取得某节点下的某属性

Element root=document.getRootElement();        
//属性名name
 Attribute attribute=root.attribute("size");

2.取得属性的文字

String text=attribute.getText();

3.删除某属性

 Attribute attribute=root.attribute("size");
  root.remove(attribute);

4.遍历某节点的所有属性

Element root=document.getRootElement();    
for(Iterator it=root.attributeIterator();it.hasNext();){
    Attribute attribute = (Attribute) it.next();
    String text=attribute.getText();
     System.out.println(text);
 }

5.设置某节点的属性和文字.

 newMemberElm.addAttribute("name", "sitinspring");

6.设置属性的文字

Attribute attribute=root.attribute("name"); attribute.setText("sitinspring");

将文档写入XML文件

1.文档中全为英文,不设置编码,直接写入的形式.

 XMLWriter writer = new XMLWriter(new  FileWriter("output.xml"));
 writer.write(document);
 writer.close();

2.文档中含有中文,设置编码格式写入的形式.

OutputFormat format = OutputFormat.createPrettyPrint();// 指定XML编码                   
format.setEncoding("GBK");    
XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);
writer.write(document);
writer.close();

Dom4j在指定位置插入节点

  • 1.得到插入位置的节点列表(list)
  • 2.调用list.add(index,elemnent),由index决定element的插入位置。
  • Element元素可以通过DocumentHelper对象得到。示例代码
Element aaa = DocumentHelper.createElement("aaa");
aaa.setText("aaa");

List list = root.element("书").elements();
list.add(1, aaa);

//更新document

字符串与XML的转换

  • 1.将字符串转化为XML
String text = "<members> <member>sitinspring</member></members>";
Document document = DocumentHelper.parseText(text);

  • 2.将文档或节点的XML转化为字符串.
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));  
Element root=document.getRootElement();    
String docXmlText=document.asXML();
String rootXmlText=root.asXML();
Element memberElm=root.element("member");
String memberXmlText=memberElm.asXML();

DOM4J编程

  • 读取xml
//读取xml文档数据:<书名>Java就业培训教程</书名>
    @Test
    public void read() throws Exception{

        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book1.xml"));

        Element root = document.getRootElement();
        Element bookname = root.element("书").element("书名");
        System.out.println(bookname.getText());
    }

这里写图片描述

  • 读取xml属性
//<书 name="yyyyyyy">
    @Test
    public void readAttr() throws Exception{

        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book1.xml"));

        Element root = document.getRootElement();
        String value = root.element("书").attributeValue("name");
        System.out.println(value);
    }

这里写图片描述

  • 向xml中添加元素
//向xml文档中添加<售价>19元</售价>
    @Test
    public void add() throws Exception{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book1.xml"));

        Element price = DocumentHelper.createElement("售价");
        price.setText("19元");

        document.getRootElement().element("书").add(price);

        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");

        XMLWriter writer = new XMLWriter(new FileOutputStream("src/book1.xml"),format);//FileOutputStream 查格式输入器format的码表"UTF-8"
        writer.write(document);  //utf-8
        writer.close();
    }
<?xml version="1.0" encoding="UTF-8"?>

<书架> 
  < name="yyyyyyy"> 
    <书名>Java就业培训教程</书名>  
    <作者>张孝祥</作者>  
    <售价>19元</售价>  
    <售价>19元</售价>
  </>  
  <> 
    <书名>JavaScript网页开发</书名>  
    <作者>黎活明</作者>  
    <售价>28.00元</售价> 
  </> 
</书架>
  • dom4j保存数据的乱码问题

    //向xml文档中添加<售价>19元</售价>
    @Test
    public void add() throws Exception{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book1.xml"));

        Element price = DocumentHelper.createElement("售价");
        price.setText("19元");

        document.getRootElement().element("书").add(price);


        XMLWriter writer = new XMLWriter(new FileWriter("src/book1.xml"));//默认查gb2312码表
        writer.write(document);  
        writer.close();
    }

结果为乱码:

<?xml version="1.0" encoding="UTF-8"?>
<���> 
  <�� name="yyyyyyy"> 
    <����>Java��ҵ��ѵ�̳�</����>  
    <����>����</����>  
    <�ۼ�>19Ԫ</�ۼ�>  
  <�ۼ�>19Ԫ</�ۼ�><�ۼ�>19Ԫ</�ۼ�></��>  
  <��> 
    <����>JavaScript��ҳ����</����>  
    <����>�����</����>  
    <�ۼ�>28.00Ԫ</�ۼ�> 
  </��> 
</���>

修改为如下:

    //向xml文档中添加<售价>19元</售价>
    @Test
    public void add() throws Exception{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book1.xml"));

        Element price = DocumentHelper.createElement("售价");
        price.setText("19元");

        document.getRootElement().element("书").add(price);

        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("gb2312");

        XMLWriter writer = new XMLWriter(new FileWriter("src/book1.xml"),format);
        writer.write(document); //gb2312 
        writer.close();
    }
<?xml version="1.0" encoding="gb2312"?>

<书架> 
  < name="yyyyyyy"> 
    <书名>Java就业培训教程</书名>  
    <作者>张孝祥</作者>  
    <售价>19元</售价>  
    <售价>19元</售价>
  </>  
  <> 
    <书名>JavaScript网页开发</书名>  
    <作者>黎活明</作者>  
    <售价>28.00元</售价> 
  </> 
</书架>

已下这种也可以解决乱码问题:

//向xml文档中添加<售价>19元</售价>
    @Test
    public void add() throws Exception{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book1.xml"));

        Element price = DocumentHelper.createElement("售价");
        price.setText("19元");

        document.getRootElement().element("书").add(price);

        XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream("src/book1.xml"),"UTF-8"));
        writer.write(document); //默认UTF-8 
        writer.close();
    }
  • 修改xml元素
//修改:<售价>19元</售价>  为209元
    @Test
    public void update() throws Exception{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book1.xml"));

        Element price = (Element) document.getRootElement().element("书").elements("售价").get(0);
        price.setText("209元");

        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");

        XMLWriter writer = new XMLWriter(new FileOutputStream("src/book1.xml"),format);
        writer.write(document);  //utf-8
        writer.close();

    }
<?xml version="1.0" encoding="UTF-8"?>

<书架> 
  < name="yyyyyyy"> 
    <书名>Java就业培训教程</书名>  
    <作者>张孝祥</作者>  
    <售价>209元</售价> 
  </>  
  <> 
    <书名>JavaScript网页开发</书名>  
    <作者>黎活明</作者>  
    <售价>28.00元</售价> 
  </> 
</书架>
  • 删除xml元素
//删除:<售价>209</售价>
    @Test
    public void delete() throws Exception{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book1.xml"));

        Element price = (Element) document.getRootElement().element("书").elements("售价").get(0);
        price.getParent().remove(price);

        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");

        XMLWriter writer = new XMLWriter(new FileOutputStream("src/book1.xml"),format);
        writer.write(document);  //utf-8
        writer.close();
    }
<?xml version="1.0" encoding="UTF-8"?>

<书架> 
  < name="yyyyyyy"> 
    <书名>Java就业培训教程</书名>  
    <作者>张孝祥</作者> 
  </>  
  <> 
    <书名>JavaScript网页开发</书名>  
    <作者>黎活明</作者>  
    <售价>28.00元</售价> 
  </> 
</书架>
  • 向指定位置增加售价结点
    //向指定位置增加售价结点
    @Test
    public void add2() throws Exception{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book1.xml"));

        Element price = DocumentHelper.createElement("售价");
        price.setText("19元");

        List list = document.getRootElement().element("书").elements();
        list.add(1, price);


        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");

        XMLWriter writer = new XMLWriter(new FileOutputStream("src/book1.xml"),format);
        writer.write(document);  //utf-8
        writer.close();

    }
<?xml version="1.0" encoding="UTF-8"?>

<书架> 
  < name="yyyyyyy"> 
    <书名>Java就业培训教程</书名>  
    <售价>19元</售价>
    <作者>张孝祥</作者> 
  </>  
  <> 
    <书名>JavaScript网页开发</书名>  
    <作者>黎活明</作者>  
    <售价>28.00元</售价> 
  </> 
</书架>
  • XPath提取xml文档数据
    @Test
    public void findWithXpath() throws Exception{
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book1.xml"));

        Element e = (Element) document.selectNodes("//书名").get(1);
        System.out.println(e.getText());
    }

这里写图片描述

user.xml

<?xml version="1.0" encoding="UTF-8"?>
<users>


    <user username="aaa" password="123"/>

    <user username="bbb" password="123"/>

    <user username="ccc" password="123"/>

</users>
    @Test
    public void findUser() throws Exception{
        String username = "aaa";
        String password = "1233";

        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/users.xml"));

        Element e = (Element) document.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");
        if(e!=null){
            System.out.println("让用户登陆成功!!");
        }else{
            System.out.println("用户名和密码不正确!!");
        }

    }
}

这里写图片描述

XPath

详情参考:http://www.w3school.com.cn/xpath/index.asp

dom4j参考资料

https://dom4j.github.io/

Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000