javaweb_XML

# 什么时xml

# xml简介

xml:eXtensible Markup Lauguage  (可扩展性标记语言)

特定:可扩展,xml中的标签都可自定义,语法严格,区分大小写

作用:xml的主要作用就是用于简单数据存储,可以用来做配置文件,也可以使用xml进行数据传输

# xml文档声明

<?xml version="1.0" encoding="UTF-8"?>
    version:版本号,固定值为1.0
    encoding:指定文档的码表,默认值为UTF-8
    standalone:指定文档是否独立yes或no

# 文档中的标签

<xml-body>
    <book id="100">
        <name>Java编程思想</name>
        <price>136</price>
    </book>
    <book id="101">
        <name>Java编程思想</name>
        <price>136</price>
        <![CDATE[
            <hello>                // 会将<hello>原样输出
        ]]>
    </book>
</xml-body>
1:文档中有且仅有一个根元素
2:元素需要正确闭合
3:元素需要正确嵌套
4:元素名称需要遵守(元素名称区分大小写,数字不能开头)

 # HTML和XML区别

html语法松散,xml语法严格
html做页面展示,xml做数据存储
html所有标签都是预定义的,xml所有标签都是自定义的

# xml约束

为何需要约束:因为xml的标签都是由用户自定义的,因此在开发时,每个人都可以根据自己的需求来定义xml标签,会导致项目中的xml难以维护,所以需要使用一定的规范机制来约束xml文件中标签的书写

约束方式一:dtd

# 创建xml文件
<?xml version="1.0" encoding="UTF-8"?>
<usermsg>
    <user>
        <name>zhangsan</name>
        <age>18</age>
        <addr>fujian</addr>
    </user>
    <user>
        <name>lisi</name>
        <age>20</age>
        <addr>guangdong</addr>
    </user>
</usermsg>

# 创建DTD文件来越苏xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!ELEMENT usermsg (user+) >
<!ELEMENT user (name,age,addr) >
<!ELEMENT name (#PCDATA) >
<!ELEMENT age (#PCDATA)>
<!ELEMENT addr (#PCDATA)>

# DTD的引入方式
可以单独写在文件中,也可以直接嵌套在xml文件中
可以在xml文件中引入第三方公共的DTD约束文件

<!-- 外部dtd的引入方式 -->
<!DOCTYPE 文档根结点 SYSTEM "DTD文件的URL">
    文档根结点:指的是当前xml中的根标签。
    SYSTEM:引入的系统中存在文件
    "DTD文件的URL":DTD存放的位置

<!-- 引入公共的DTD -->
<!DOCTYPE 文档根结点 PUBLIC "DTD名称" "DTD文件的URL">
    文档根结点:指的是当前xml中的根标签。
    PUBLIC:表示当前引入的DTD是公共的DTD

<!-- 直接在xml文件中写DTD -->
<!DOCTYPE  根标签名 [
    具体的标签的约束
]>
    <?xml version="1.0" encoding="UTF-8"?>
    <usermsg>
        <user>
            <name>zhangsan</name>
            <age>18</age>
            <addr>fujian</addr>
        </user>
        <user>
            <name>lisi</name>
            <age>20</age>
            <addr>guangdong</addr>
        </user>
    </usermsg>

    <?xml version="1.0" encoding="UTF-8" ?>
    <!ELEMENT usermsg (user+) >
    <!ELEMENT user (name,age,addr) >
    <!ELEMENT name (#PCDATA) >
    <!ELEMENT age (#PCDATA)>
    <!ELEMENT addr (#PCDATA)>

元素
<!ELEMENT 标签名 约束>  约束来限定当前标签中可以有的子标签,或者当前标签中可以书写的内容
    “约束”中可以使用一些符号定义标签具体的出现次数
        ?       零次或者一次
        *       零次或者多次
        +       一次或者多次 usermsg(user+) 表示当前的usermsg标签下可以有一个或者多个user标签
        ,       用来限定当前的子标签出现的顺序user(name,age,addr)user标签下只能有name age addr 子标签,并且必须按照name  age  addr的顺序书写
        |       user (name|age,addr) user下可以name或者age ,但必须有addr,并且addr必须name或age后面
        #PCDATA 表明该元素可包含任何字符数据,但不能在其中包含任何子元素。只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明
        EMPTY   表明该元素不能有任何子元素或文本,仅可以使用属性。
        ANY     表该元素中可以包含任何DTD中定义的元素内容 如:<!ELEMENT note ANY>
        <!ELEMENT age EMPTY >          当前的age标签是个空标签,它不能有文本内容

 约束方式二:schema

# DTD在约束xml时只能引入一个DTD,同时DTD无法对属性及标签中的数据类型做数据类型的限定
<!-- web.xml中使用了schema作为约束 -->
<!-- 约束其书写的格式,例如在价格标签中,schema中规定至只能写入数字,如果写入其它形式数据,就会报错 -->

# 定义schema文件
在定义Schema文件的时候,由于这个Schema文件本身就是xml,它也要受到别的约束。而这个约束是W3C组织提前定义好的,
在Schema文件中需要提前引入进来在根标签中使用属性进行进入:
<schema xmlns="http://www.w3.org/2001/XMLSchema" 引入W3C定义的schema书写的规范
targetNamespace="http://www.doaoao.com/test" 给当前的Schema文件起名字(命名空间)
作用是当哪个xml要引入这个schema约束的时候,必须通过当前targetNamespace 后面书写的uri地址来引入

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name></display-name>    
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

# xml解析

数据存储在xml文件中,如果想要读取到java内存中,这时就要对xml进行解析

解析xml两个思想:

<!--dom-->
    dom会将xml文档加载进内存,形成一颗dom树(document对象),将文档的各个组成部分封装为对象。
    优点:可以对dom树进行增删改查。
    缺点:dom树非常占内存,解析速度慢。    
<!--sax-->
    逐行读取,基于事件驱动
    优点:不占内存,速度快
    缺点:只能读取,不能回写

常用的解析器:

jaxp,jdom,dom4j

# 利用dom4j解析xml文件例子(遍历指定元素)

package testxml;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
public class don4j_test {
    @Test
    public void test1() throws DocumentException{
        // 创建一个xml解析对象
        SAXReader reader = new SAXReader();
        
        // 将xml文件加载到document对象中
        Document document = reader.read("src/MyXml.xml");
        
        // 获取xml中的根节点
        Element root = document.getRootElement();
        
        // 获取当前节点的所有子节点(返回一个List对象)
        List list = root.elements();
        Element thirdBook = (Element)list.get(1);    // "1"表示的是取得根节点中的第二个子节点
        String name = thirdBook.element("name").getText();
        System.out.println(name);
    }
}

# 利用don4j解析xml例子(遍历所有节点)

package testxml;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
public class don4j_test {
    @Test
    public void test1() throws DocumentException{
        // 创建一个xml解析对象
        SAXReader reader = new SAXReader();
        
        // 将xml文件加载到document对象中
        Document document = reader.read("src/MyXml.xml");
        
        // 获取xml中的根节点
        Element root = document.getRootElement();
        treeSelect(root);
    }
    
    // 利用递归遍历所有节点
    private void treeSelect(Element ele){
        // 输出当前节点的名字
        System.out.println(ele.getName());
        for(int i=0;i<ele.nodeCount();i++){
            // 获取下标为i的节点
            Node node = ele.node(i);
            // 判断当前的标签是否为标签
            if(node instanceof Element){
                treeSelect((Element)node);
            }else{
                System.out.println(node.getText());
            }
        }
    }
}

# 使用xpath读取xml中的节点

package testxml;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;s
import org.junit.Test;
public class XpathTst {
    @Test
    public void test1() throws DocumentException{
        SAXReader reader = new SAXReader();
        Document document = reader.read("src/MyXml.xml");
        Node node_name = document.selectSingleNode("/xml-body/book/name");
        System.out.println(node_name.getText());
        
        // 获取xml-body下的第二个book
        Node node_name2 = document.selectSingleNode("/xml-body/book[1]/name");
        System.out.println(node_name2.getText());
        
        // 获取属性id的值
        Node node_name3 = document.selectSingleNode("/xml-body/book/attribute::id");
        System.out.println(node_name3.getText());    
    }
}

 # 使用xpath遍历所有节点

package testxml;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
public class XpathTst {
    @Test
    public void test1() throws DocumentException{
        SAXReader reader = new SAXReader();
        Document document  = reader.read("src/MyXml.xml");
        List list = document.selectNodes("//*");
        for (int i=0;i<list.size();i++){
            Node node = (Node)list.get(i);
            System.out.println(node.getName() + "	" + node.getText());
        }
    }
}

 待补充... 

待补充...

原文地址:https://www.cnblogs.com/Doaoao/p/10602820.html