zoukankan      html  css  js  c++  java
  • 用dom4j操作xml文件

      XML的全称是eXtensible Markup Language,即“可扩展标记语言”。XML文件的作用主要是数据存储,文件配置,数据传输。

      html与xml的区别是:①html语法松散,xml语法严格;②html做页面展示,xml做数据存储;③html的所有标签都是预定义的,xml所有标签都是自定义的。xml文档中必须有且只能有一个根元素;元素需要正确闭合元素需要正确嵌套元素名称要遵守两点,一是元素名称区分大小写,二是数字不能开头属性值必须用引号引起来,单双引号都行;xml文档中的注释符为<!--   -->;xml文档中对于可能引起歧义的文本要使用转义字符,或者用<![CDATA[数据内容]],这样的话,数据内容可以原样显示。

    <?xml version="1.0" encoding="UTF-8" ?>
    <自定义标签>
        ...
    </自定义标签> 

      xml的书写规则,有DTDschema。

      文档类型定义(DTD)可以定义合法的XML文档构建模块,约束自定义的语法规则。它使用一系列合法的元素来定义文档的结构。DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。

       内部的 DOCTYPE 声明:

    <!DOCTYPE 根元素 [元素声明]>
    

       带有 DTD 的 XML 文档实例:

    <?xml version="1.0"?>
    <!DOCTYPE note [
      <!ELEMENT note (to,from,heading,body)>
      <!ELEMENT to      (#PCDATA)>
      <!ELEMENT from    (#PCDATA)>
      <!ELEMENT heading (#PCDATA)>
      <!ELEMENT body    (#PCDATA)>
    ]>
    <note>
      <to>George</to>
      <from>John</from>
      <heading>Reminder</heading>
      <body>Don't forget the meeting!</body>
    </note>
    

       以上 DTD 解释如下:
      !DOCTYPE note (第二行)定义此文档是 note 类型的文档。
      !ELEMENT note (第三行)定义 note 元素有四个元素:"to、from、heading,、body"
      !ELEMENT to (第四行)定义 to 元素为 "#PCDATA" 类型
      !ELEMENT from (第五行)定义 from 元素为 "#PCDATA" 类型
      !ELEMENT heading (第六行)定义 heading 元素为 "#PCDATA" 类型
      !ELEMENT body (第七行)定义 body 元素为 "#PCDATA" 类型

      假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:

    <!DOCTYPE 根元素 SYSTEM "文件名">
    

       这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD:

    <?xml version="1.0"?>
    <!DOCTYPE note SYSTEM "note.dtd">
    <note>
    <to>George</to>
    <from>John</from>
    <heading>Reminder</heading>
    <body>Don't forget the meeting!</body>
    </note> 
    

       这是包含 DTD 的 "note.dtd" 文件:

    <!ELEMENT note (to,from,heading,body)>
    <!ELEMENT to (#PCDATA)>
    <!ELEMENT from (#PCDATA)>
    <!ELEMENT heading (#PCDATA)>
    <!ELEMENT body (#PCDATA)>
    

       通过 DTD,我们的每一个 XML 文件均可携带一个有关其自身格式的描述。通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。我们的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。我们还可以使用 DTD 来验证自身的数据。

      XML Schema 的作用是定义 XML 文档的合法构建模块,类似 DTD。它是基于 XML 的 DTD 替代者。XML Schema 描述 XML 文档的结构。XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD)。

      XML Schema 最重要的能力之一就是对数据类型的支持。例:

    user.xsd
    
    <?xml version="1.0"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    	elementFormDefault="qualified" 
    	targetNamespace="http://www.itszt2.com"
    	xmlns="http://www.itszt2.com">	
    	<xs:element name="用户" type="type_user"></xs:element>
    	<!-- 复合类型;元素嵌套;自定义数据类型 -->
    	<xs:complexType name="type_user">
    		<!-- 规定显示的先后顺序 -->
    		<xs:sequence>		
    			<xs:element name="姓名" type="type_xm"></xs:element>
    			<xs:element name="年龄" type="type_nl"></xs:element>			
    			<xs:element name="性别" type="type_xb" minOccurs="1"
    				maxOccurs="999999999"></xs:element>			
    			<xs:element name="工资" type="type_gz">
    			</xs:element>
    			<xs:element name="出生日期" type="xs:date"></xs:element>
    		</xs:sequence>	
    	</xs:complexType>
    
    	<!-- 定义姓名的类型 -->
    	<xs:simpleType name="type_xm">
    		<xs:restriction base="xs:string">
    			<xs:pattern value="w{6,10}" />
    		</xs:restriction>
    	</xs:simpleType>
    
    	<!-- 定义年龄的类型 -->
    	<xs:simpleType name="type_nl">
    		<xs:restriction base="xs:integer">
    			<xs:minInclusive value="0"></xs:minInclusive>
    			<xs:maxInclusive value="100"></xs:maxInclusive>
    		</xs:restriction>
    	</xs:simpleType>
    
    	<!-- 定义性别类型 -->
    	<xs:simpleType name="type_xb">
    		<xs:restriction base="xs:string">
    			<xs:enumeration value="男" />
    		</xs:restriction>
    	</xs:simpleType>
    
    	<!-- 定义属性 -->
    	<xs:complexType name="type_gz">
    		<xs:attribute name="单位" type="xs:string" use="required" />
    		<xs:attribute name="num" type="xs:decimal" />
    	</xs:complexType>
    </xs:schema>
    
    -------------------------------------------------------------
    test.xml
    
    <?xml version="1.0"?>
    <用户 xmlns="http://www.itszt2.com" 
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="
    	http://www.itszt2.com
     	user.xsd"> 	
         
     	<姓名>hehe123</姓名>
    	<年龄>20</年龄>
    	<性别>男</性别>
    	<工资 单位="元" num="123.45" ></工资>
    	<出生日期>1999-10-10</出生日期>	
    	
    </用户> 

      上述演示中,xmlns="http://www.w3school.com.cn"  规定了默认命名空间的声明。此声明会告知 schema 验证器,在此 XML 文档中使用的所有元素都被声明于 "http://www.w3school.com.cn" 这个命名空间。

      定义简易元素的语法:

    <xs:element name="xxx" type="yyy"/>
    

       上面的 xxx 指元素的名称,yyy 指元素的数据类型。XML Schema 拥有很多内建的数据类型。  

    最常用的类型是:
        xs:string
        xs:decimal
        xs:integer
        xs:boolean
        xs:date
        xs:time
    

       简易元素可拥有指定的默认值或固定值。当没有其他的值被规定时,默认值就会自动分配给元素。在下面的例子中,缺省值是 "red":

    <xs:element name="color" type="xs:string" default="red"/>
    

       固定值同样会自动分配给元素,并且我们无法规定另外一个值。在下面的例子中,固定值是 "red":

    <xs:element name="color" type="xs:string" fixed="red"/>
    

       简易元素无法拥有属性。假如某个元素拥有属性,它就会被当作某种复合类型。但是属性本身总是作为简易类型被声明的。

      定义属性的语法是:  

    <xs:attribute name="xxx" type="yyy"/>
    

       在此处,xxx 指属性名称,yyy 则规定属性的数据类型。XML Schema 拥有很多内建的数据类型,与上面定义元素的类型相同。

      限定(restriction)用于为 XML 元素或者属性定义可接受的值。对 XML 元素的限定被称为 facet。

      复合元素指包含其他元素及/或属性的 XML 元素。

    有四种类型的复合元素:
        空元素
        包含其他元素的元素
        仅包含文本的元素
        包含元素和文本的元素
    注释:上述元素均可包含属性!   

       比如,导入xsd约束文档:

    (1)编写根标签
    (2)引入实例名称空间 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    (3)引入名称空间 xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"	
    (4)引入默认的名称空间 

      在Java技术中,对xml文件的操作也是一个重要的部分。一般来说,xml的格式比较标准,在存储数据方面有着广泛的运用,例如,很多软件(如tomcat,nginx,redis等),包括框架(如Spring,mybatis等)中的一系列配置文件,就广泛地采用了xml来储存配置信息。接下来,我们看如何使用dom4j来对xml文件中的元素进行增删改查。

      在使用dom4j技术时,我们需要在项目中引入dom4j-1.6.1.jar和jaxen-1.1-beta-6.jar两个jar包,并设置为依赖,这样的话,我们就可以使用这两个jar包中的API了。当然,也可以导入dom4j的其他版本,请根据需要而定。

      我们先来看读取一个xml文件,并打印到控制台上:  

     1 import org.dom4j.Document;
     2 import org.dom4j.DocumentException;
     3 import org.dom4j.io.SAXReader;
     4 import org.dom4j.io.XMLWriter;
     5 import java.io.File;
     6 import java.io.IOException;
     7 /**
     8  * 读取一个xml文件,并将其内容打印到控制台上
     9  */
    10 public class Test1 {
    11     public static void main(String[] args) {
    12         String filePath = "book.xml";
    13         Document document = readXMLFile(filePath);
    14         printToControl(document);
    15     }
    16     private static void printToControl(Document document) {//打印到控制台
    17         try {
    18             XMLWriter writer = new XMLWriter();
    19             writer.write(document);
    20             writer.flush();
    21             writer.close();
    22         } catch (IOException e) {
    23             e.printStackTrace();
    24         }
    25     }
    26     private static Document readXMLFile(String filePath) {//读取一个xml文件
    27         SAXReader saxReader = new SAXReader();
    28         File file = new File(filePath);
    29         try {
    30             return saxReader.read(file);
    31         } catch (DocumentException e) {
    32             e.printStackTrace();
    33         }
    34         return null;
    35     }
    36 }

      执行上述代码,读取到名称为book.xml的文件内容如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <图书信息 desc="书籍信息">
      <图书>
        <书名>《战争与和平》</书名>
        <作者>列夫·托尔斯泰</作者>
        <内容>描述了拿破仑争霸时期,以俄国为社会背景的爱恨情仇</内容>
      </图书>
      <图书>
        <书名>《红楼梦》</书名>
        <作者>曹雪芹</作者>
        <内容>以贾王史薛四大家族为背景,描述了贾宝玉与林黛玉的感人爱情故事</内容>
      </图书>
    </图书信息>

      我们还可以把读取到的xml文件储存到一个文件里,在此,我们在上述的Test1类里增加一个储存xml文件的方法,代码如下:

    //保存xml文件到指定路径
        static boolean saveDocument(Document document,String filePath){
            OutputFormat outputFormat = OutputFormat.createPrettyPrint();
            outputFormat.setEncoding("UTF-8");
            XMLWriter writer = null;
            try {
                writer = new XMLWriter(new FileWriter(filePath), outputFormat);
                writer.write(document);
                writer.flush();
                writer.close();
                return true;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }

      上述代码执行成功后,会在项目下创建一个名称为book2.xml的文件,并返回为true。

      另外,我们还可以创建一个xml文件,这个方法返回一个Document对象,代码如下:

    //创建一个xml文件
        public static Document createXMLDoc() {
            Document document = DocumentHelper.createDocument();
            Element root =  DocumentHelper.createElement("图书信息");
            document.setRootElement(root);
            root.addAttribute("desc","书籍信息");
    
            Element book1 = root.addElement("图书");
            Element book1_name = book1.addElement("书名");
            book1_name.addText("《战争与和平》");
            Element book1_author = book1.addElement("作者");
            book1_author.addText("列夫·托尔斯泰");
            Element book1_content = book1.addElement("内容");
            book1_content.addText("描述了拿破仑争霸时期,以俄国为社会背景的爱恨情仇");
    
            Element book2 = root.addElement("图书");
            Element book2_name = book2.addElement("书名");
            book2_name.addText("《红楼梦》");
            Element book2_author = book2.addElement("作者");
            book2_author.addText("曹雪芹");
            Element book2_content = book2.addElement("内容");
            book2_content.addText("以贾王史薛四大家族为背景,描述了贾宝玉与林黛玉的感人爱情故事");
            return document;
        }

      我们还可以获取父元素下指定名称的第一个节点,代码如下:

    //获取父元素下的指定名称第一个节点
        static Element getFirstChildNodeByName(Element root,String nodeName){
            return (Element)root.selectSingleNode(nodeName);
        }

      我们还可以父元素下指定名称的所有节点信息,代码如下:

    //获取父元素下的指定名称的所有节点
        static List<Element> getAllChildNodeByName(Element root, String nodeName){
            return root.selectNodes(nodeName);
        }

      我们再来看删除指定节点的属性,代码如下:

    //删除指定节点的属性
        static void removeAttr(Element root,String nodeName,String attrName){
            Element node = root.element(nodeName);
            Attribute attr = node.attribute(attrName);
            node.remove(attr);
        }

      更改指定节点的属性值,代码如下:

    //更改指定节点的属性值
        static void updateAttrVal(Element root,String nodeName,String attrName,String newValue){
            Element node = root.element(nodeName);
            Attribute attr = node.attribute(attrName);
            attr.setValue(newValue);
        }

      为指定节点添加属性值,代码如下:

    //为指定节点添加属性
        static void addAttr(Element node, String attrKey, String attrValue) {
            node.addAttribute(attrKey, attrValue);
        }

      对指定节点添加子节点及其文本内容,代码如下:

    //对指定节点添加子节点及其文本内容
        static Element addNode(Element parentNode,String childNode){
            Element element = parentNode.addElement(childNode);
            element.setText("haha");
            return element;
        }
  • 相关阅读:
    判断窗体 show完成
    【洛谷1349】广义斐波那契数列
    【洛谷2744 】【CJOJ1804】[USACO5.3]量取牛奶Milk Measuring
    【洛谷T7153】(考试) 中位数
    【洛谷T7152】(考试题目)细胞
    【洛谷1962】 斐波那契数列
    【洛谷1855】 榨取kkksc03
    【HDU2255】奔小康赚大钱
    【洛谷1402】酒店之王
    【洛谷1607】【USACO09FEB】庙会班车
  • 原文地址:https://www.cnblogs.com/lizhangyong/p/8386522.html
Copyright © 2011-2022 走看看