(二)XML基础(2)

三、解析   

  •   服务端解析

        JDK:
            DOM
            SAX
            JAXB    java and xml Binding

        开源(一般都是用开源的)
            JDOM   
            DOM4J:hibernate框架就是使用dom4j来解析映射文件。
            X-Stream:java跟XML之间转换的工具(java转成xml文件/字符串,
                              xml文件/字符串转为java对象)


  • DOM/SAX/JDom/Dom4J之间的区别:

DOM/JDom:将XML文件中的内容一次性的读取到内存中。读取数据量比较少的数据有优势。

SAX:      基于事件的驱动。读取数据量比较大的XML文件。



  • 案例一(用DOM解析)

student.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/student"
    xmlns:tns="http://www.example.org/student" elementFormDefault="qualified">
    <!-- xmlns:xsd="http://www.w3.org/2001/XMLSchema" 字段表示引用w3c -->
    
    <xsd:element name="other" ></xsd:element>
    
    
    <xsd:element name="root" > <!-- 创建xml文档的根节点 -->
        <xsd:complexType>
            <xsd:sequence >
                <xsd:element name="student" maxOccurs="5" > <!-- 创建student节点,且这个节点在xml文档中最多出现5次 -->
                    <xsd:complexType>        
                        <xsd:sequence>
                            <xsd:element name="name" type="xsd:string"></xsd:element>
                            <xsd:element name="age" >
                                <xsd:simpleType>
                                <!-- 设置元素节点的值为10~50之间,且为整型 -->
                                    <xsd:restriction base="xsd:integer">
                                        <xsd:maxInclusive value="50"></xsd:maxInclusive>
                                        <xsd:minInclusive value="10"></xsd:minInclusive>
                                    </xsd:restriction>
                                </xsd:simpleType>
                            </xsd:element>
                            <xsd:element name="sex" type="tns:sex"></xsd:element>  <!-- 引用本文件自定义的类型,用用tns前缀 -->
                            <xsd:element name="content" type="xsd:string"></xsd:element>
                        </xsd:sequence>
                        <xsd:attribute name="id" type="xsd:string" ></xsd:attribute> <!-- 属性 的定义一定要放在最后面定义-->
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>    
        </xsd:complexType>
    </xsd:element>
    
    <xsd:simpleType name="sex">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="男"></xsd:enumeration>
            <xsd:enumeration value="女"></xsd:enumeration>
        </xsd:restriction>
    
    </xsd:simpleType>
    
</xsd:schema>

student.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<other xmlns="http://www.example.org/student" xmlns:jdbc="http://www.example.org/jdbc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.example.org/student student.xsd        http://www.example.org/jdbc jdbc.xsd ">
    <root>
        <student id="01">
            <name>张三</name>
            <age>15</age>
            <sex></sex>
            <content>张三备注</content>
        </student>

        <student id="02">
            <name>被修改后的张三</name>
            <age>25</age>
            <sex></sex>
            <content>李四备注</content>
        </student>
        <student>
            <name>王五</name>
            <age>10</age>
            <sex></sex>
            <content><![CDATA[这是CDATA节点中的同容^*&%IO(%$R^U*&P^&RI*YHOf]]></content>
        </student>
    </root>


</other>

TestDom.java

package dom;

import java.io.File;

import javax.xml.crypto.dsig.Transform;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class TestDom {

    public static void main(String[] args) {

        // TestDom.readXml();
        // TestDom.delXml();
        //    TestDom.updateXml();
        TestDom.insertXml();
    }



    private static void readXml() {
        File file = new File("./src/student.xml");
        // 得到 DOM 解析器的工厂实例
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = null;
        Document document = null;
        try {
            // 得到DOM解析器
            documentBuilder = factory.newDocumentBuilder();
            // 解析xml文档,得到DOM对象
            document = documentBuilder.parse(file);
            // 获取文档的根节点
            Element rootElement = document.getDocumentElement();
            // 获取根节点中的student节点,返回NodeList集合
            NodeList nodeList = rootElement.getElementsByTagName("student");

            for (int i = 0; i < nodeList.getLength(); i++) {
                Element student = (Element) nodeList.item(i);

                String stu_id = student.getAttribute("id");

                // 获取student元素节点中第一个名叫name的元素节点,中的第一个子节点的值。
                String stu_name = student.getElementsByTagName("name").item(0).getFirstChild().getNodeValue();
                String age = student.getElementsByTagName("age").item(0).getFirstChild().getNodeValue();
                String sex = student.getElementsByTagName("sex").item(0).getFirstChild().getNodeValue();
                String content = student.getElementsByTagName("content").item(0).getFirstChild().getNodeValue();
                System.out.println(
                        "id=" + stu_id + "stu_name=" + stu_name + "age=" + age + "sex=" + sex + "content=" + content);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void delXml() {

        File file = new File("./src/student.xml");

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = null;
        Document document = null;
        try {
            builder = factory.newDocumentBuilder();
            document = builder.parse(file);

            Element rootElement = document.getDocumentElement();
            Element parenElement = (Element) rootElement.getElementsByTagName("root").item(0);
            NodeList nodeList = rootElement.getElementsByTagName("student");

            for (int i = 0; i < nodeList.getLength(); i++) {

                Element student = (Element) nodeList.item(i);

                // 移除属性id=3的 student元素节点
                if (student.getAttribute("id").equals("03")) {
                    // 要移除某个节点,必须这个节点的父节点的remove方法来移除
                    parenElement.removeChild(student);
                    break;
                }
            }

            // 重新将Document整个文档对象写回到XML文件中。
            // 这段代码的关键是将文档内容保存在文件中
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();

            // 设置输出格式,以utf-8且缩进格式
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");

            DOMSource source = new DOMSource(document);
            StreamResult streamResult = new StreamResult(file);
            transformer.transform(source, streamResult);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void updateXml() {
        File xmlFile = new File("./src/student.xml");
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = null;
        Document document = null;
        try {
            documentBuilder = builderFactory.newDocumentBuilder();
            document = documentBuilder.parse(xmlFile);

            Element rootElement = document.getDocumentElement();

            NodeList nodeList = rootElement.getElementsByTagName("student");

            for (int i = 0; i < nodeList.getLength(); i++) {
                Element student = (Element) nodeList.item(i);
                String stu_id = student.getAttribute("id");

                if (stu_id.equals("02")) {
                    // 修改属性id=02的信息
                    student.getElementsByTagName("name").item(0).getFirstChild().setNodeValue("被修改后的张三");
                    student.getElementsByTagName("sex").item(0).getFirstChild().setNodeValue("女");
                }

            }

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();

            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

            DOMSource domSource = new DOMSource(document);
            StreamResult result = new StreamResult(xmlFile);
            transformer.transform(domSource, result);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    
    private static void insertXml() {
            File xmlFile=new File("./src/student.xml");
            DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder=null;
            Document document=null;
            try {
                documentBuilder=builderFactory.newDocumentBuilder();
                document=documentBuilder.parse(xmlFile);
                
                
                Element rootElement=document.getDocumentElement();
                //往root节点下添加节点
                Element parenElment=(Element)rootElement.getElementsByTagName("root").item(0);
                //往studentElment节点下添加节点
                Element studentElment=document.createElement("student");
                
                Element nameElment=document.createElement("name");
                nameElment.setTextContent("王五");
                
                Element ageElement=document.createElement("age");
                ageElement.setTextContent("10");
                
                Element sexElment=document.createElement("sex");
                sexElment.setTextContent("男");
                
                Element contentElement=document.createElement("content");
                contentElement.appendChild(document.createCDATASection("这是CDATA节点中的同容^*&%IO(%$R^U*&P^&RI*YHOf"));
                
                //把节点添加到父节点之后
                parenElment.appendChild(studentElment);
                studentElment.appendChild(nameElment);
                studentElment.appendChild(ageElement);
                studentElment.appendChild(sexElment);
                studentElment.appendChild(contentElement);
                
                
                TransformerFactory transformerFactory=TransformerFactory.newInstance();
                Transformer transformer=transformerFactory.newTransformer();
                
                transformer.setOutputProperty(OutputKeys.INDENT, "yes");
                transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
                
                DOMSource xmlSource=new DOMSource(document);
                StreamResult outputTarget=new StreamResult(xmlFile);
                
                transformer.transform(xmlSource, outputTarget);
    
                
            } catch (Exception e) {
            }

    }
}


  • 案例二(用开源工具dom4j解析)

  • 前提: 导入dom4j 的jar包
  • student.xml
<?xml version="1.0" encoding="UTF-8"?>

<other xmlns="http://www.example.org/student" xmlns:jdbc="http://www.example.org/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/student student.xsd        http://www.example.org/jdbc jdbc.xsd ">  
    <root> 
        <student id="01"> 
            <name>张三</name>  
            <age>15</age>  
            <sex></sex>  
            <content>张三备注</content> 
        </student>  
        <student id="02"> 
            <name>被修改后的张三</name>  
            <age>25</age>  
            <sex></sex>  
            <content>李四备注</content> 
        </student>  
        <student id="03">
            <name>新增</name>
            <age>12</age>
            <sex></sex>
            <content><![CDATA[#$%^#$%#$^]]></content>
        </student>
    </root> 
</other>
  • Test_dom4j.java
package dom;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.List;

import javax.xml.transform.sax.SAXResult;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.SAXWriter;
import org.dom4j.io.XMLWriter;

public class Test_dom4j {

    public static void main(String[] args) {
        // Test_dom4j.readXml();
        // Test_dom4j.delXml();
        // Test_dom4j.updateXml();
        Test_dom4j.insertXml();
    }

    private static void delXml() {

        File xmlFile = new File("./src/student.xml");
        SAXReader saxReader = new SAXReader();

        try {
            Document document = saxReader.read(xmlFile);

            Element rootElement = document.getRootElement();

            Element parenElement = (Element) rootElement.elements("root")
                    .get(0);

            List<Element> list = parenElement.elements("student");

            for (Element student : list) {

                String id = student.attributeValue("id");

                if (id.equals("03")) {
                    // 只能有父节点的remove方法移除
                    parenElement.remove(student);
                    break;
                }
            }

            // 将更改的Document节点重新写回到XML文件中
            OutputStream outputStream = new FileOutputStream(xmlFile);
            XMLWriter xmlWriter = new XMLWriter(outputStream);
            xmlWriter.write(document);
            xmlWriter.flush();
            xmlWriter.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void readXml() {

        // 创建一个xml的解析器
        File xmlFile = new File("./src/student.xml");
        SAXReader reader = new SAXReader();

        try {
            // 获取文档对象
            Document document = reader.read(xmlFile);

            // 获取根节点,注意这里的Element对象必须是org.dom4j.Element类的对象,不同于DOM方法解析xml文件
            Element rootElement = document.getRootElement();

            // 获取root节点
            Element parenElment = (Element) rootElement.elements().get(0);

            List<Element> list = parenElment.elements("student");

            for (Element student : list) {
                String stu_id = student.attributeValue("id");

                String name = student.element("name").getText();
                String age = student.elementText("name"); // 相当于student.element("age").getText();
                String sex = student.elementText("sex");
                String content = student.elementText("content");

                System.out.println("id=" + stu_id + "name=" + name + "age="
                        + age + "sex=" + sex + "content" + content);

            }

        } catch (DocumentException e) {

            e.printStackTrace();
        }
    }

    private static void updateXml() {
        File xmlFile = new File("./src/student.xml");
        SAXReader saxReader = new SAXReader();

        try {
            Document document = saxReader.read(xmlFile);

            Element rootElement = document.getRootElement();

            Element parenElement = (Element) rootElement.elements("root")
                    .get(0);

            List<Element> stuList = parenElement.elements("student");

            for (Element student : stuList) {
                String id = student.attributeValue("id");

                if (id.equals("01")) {
                    student.element("name").setText("修改后的01");
                    student.element("age").setText("22");
                    // 先把CDATA节点删除再添加
                    student.remove(student.element("content"));
                    student.addElement("content").addCDATA("$#^%$&*$674");

                }
            }

            // 保存修改后的数据
            OutputStream outputStream = new FileOutputStream(xmlFile);

            OutputFormat format = OutputFormat.createPrettyPrint();

            format.setIndent(true);
            format.setIndent("	");
            format.setEncoding("UTF-8");
            format.setTrimText(true);

            XMLWriter xmlWriter = new XMLWriter(outputStream, format);
            xmlWriter.write(document);
            xmlWriter.flush();
            xmlWriter.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void insertXml() {
        File xmlFile=new File("./src/student.xml");
        
        SAXReader saxReader=new SAXReader();
    
        try {
            Document document=saxReader.read(xmlFile);
            
            Element rootElement=document.getRootElement();
            
            Element parenElement=rootElement.element("root");
            
            Element studentElement=parenElement.addElement("student");
            studentElement.addAttribute("id", "03");
            
            studentElement.addElement("name").setText("新增");
            studentElement.addElement("age").setText("12");
            studentElement.addElement("sex").setText("男");
            studentElement.addElement("content").addCDATA("#$%^#$%#$^");
            
            OutputStream out=new FileOutputStream(xmlFile);
            OutputFormat format=OutputFormat.createPrettyPrint();
            
            format.setIndent(true);
            format.setIndent("	");;
            
            format.setEncoding("UTF-8");
            format.setTrimText(true);
            
            XMLWriter xmlWriter=new XMLWriter(out,format);
            xmlWriter.write(document);
            xmlWriter.flush();
            xmlWriter.close();
                    
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


四、字符串和XML对象的转换

  • Test_Dom4j_Convert.java
package dom;

import java.io.File;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class Test_Dom4j_Convert {
    
    public static void main(String[] args) {
         //Test_Dom4j_Convert.StringtoXml();
        Test_Dom4j_Convert.XmltoString();
        
    }

    /**
     * 把String 转为  xml对象
     */
    private static void StringtoXml() {
        String xml_str="<root><name>admin</name><age>21</age></root>";
        
        try {
            Document document=DocumentHelper.parseText(xml_str);
            Element rootElement=document.getRootElement();
            
            String name=rootElement.element("name").getText();
            String age=rootElement.elementText("age");
            
            System.out.println("name="+name+"	 age="+age);
            
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
    
    
    private static void XmltoString() {
        File xmlFile=new File("./src/student.xml");
        
        SAXReader saxReader=new SAXReader();
        
        try {
            Document document=saxReader.read(xmlFile);
            
            Element rootElement=document.getRootElement();
            
            Element parenElement=(Element)rootElement.elements("root").get(0);
            
            String xmltoString=parenElement.asXML();
            
            System.out.println(xmltoString);
        
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        
    }
}
  • student.xml
<?xml version="1.0" encoding="UTF-8"?>

<other xmlns="http://www.example.org/student" xmlns:jdbc="http://www.example.org/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/student student.xsd        http://www.example.org/jdbc jdbc.xsd ">  
    <root> 
        <student id="01"> 
            <name>张三</name>  
            <age>15</age>  
            <sex></sex>  
            <content>张三备注</content> 
        </student>  
        <student id="02"> 
            <name>被修改后的张三</name>  
            <age>25</age>  
            <sex></sex>  
            <content>李四备注</content> 
        </student>  
        <student id="03">
            <name>新增</name>
            <age>12</age>
            <sex></sex>
            <content><![CDATA[#$%^#$%#$^]]></content>
        </student>
    </root> 
</other>


原文地址:https://www.cnblogs.com/shyroke/p/6804396.html