天天看點

Java學習路線-45:XML快速入門(1)- XML、DTD、JAXP、Schema第1 章 : XML入門第2 章 : DTD(文檔類型定義)第3 章: XML解析之JAXP第4 章 : Schema:基于XML的DTD替代者

第1 章 : XML入門

課時1 XML簡介

eXtensible Markup Language

主要使用1.0版本

語言 中文名稱 用途
html 标記型語言 顯示資料
xml 可擴充标記型語言 存儲資料

課時2 XML的應用

1、傳輸資料

2、表示有關系的資料

3、配置檔案

課時3 XML的文檔聲明

1)xml的文檔聲明

(2)定義元素(标簽)

(3)注釋

(4)特殊字元

(5)CDATA區

(6)PI指令

檔案

*.xml

1、xml的文檔聲明

必須寫在第一行第一列

<?xml version="1.0" encoding="gbk" ?>      

屬性:

version 版本 1.0

encoding 編碼 gbk/utf-8

standalone 依賴其他檔案 yes/no

課時4 XML中文亂碼問題解決

<?xml version="1.0" encoding="gbk" ?>
<person>
    <name>張三</name>
    <age>23</age>
</person>        

課時5 XML元素的定義

1、隻能有一個根标簽

2、合理嵌套

3、空格和換行都會當做原始内容解析

4、有開始必須有結束

<person></person>      

5、标簽沒有内容,可以在标簽内結束

<person />      

标簽命名規則

(1)區分大小寫

(2)不能以數字下劃線開頭

(3)不能以xml、XML、Xml等開頭

(4)不能包含空格和冒号

(5)标簽可以是中文

課時6 XML屬性的定義

html和xml都是标記型文檔,可以有屬性

<person id="001"></person>      

屬性要求

(1)一個标簽可以有多個屬性

(2)屬性名稱不能相同

(3)屬性名稱與屬性值之間使用等号(=)

(4)屬性值使用引号(單引号或雙引号)包起來

(5)屬性名命名貴方和元素的命名規範一緻

課時7 XML注釋

<!--  這裡是注釋 -->      

注釋不能嵌套

注釋不能放到第一行

課時8 XML特殊字元

>

&gt;

<

&lt;

課時9 XML的CDATA區

可以解決多個字元都需要轉義的操作

特殊字元會當做文本内容

<![CDATA[ 内容 ]]>      

課時10 XML的PI指令

Processing Instruction

可以在xml中設定樣式

隻能對英文标簽起作用

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/css" href="./demo.css" ?>
<person>
    <name>張三</name>
    <age>23</age>
</person>        

demo.css

name{
    color: green;
}      

課時11 XML限制簡介

1、xml文法總結

(1)所有xml元素都必須有關閉标簽

(2)xml标簽對大小寫敏感

(3)xml必須正确嵌套

(4)xml必須有且隻有一個根元素

(5)xml屬性值需要加引号

(6)特殊字元必須轉義

(7)原樣輸出文本使用

<![CDATA[]]>

(8)xml中的空格、回車換行在解析時會被保留

2、xml的限制

(1)dtd限制

(2)scheme限制

第2 章 : DTD(文檔類型定義)

課時12 DTD快速入門

*.dtd

,使用idea打開會提示

文檔類型定義(DTD,Document Type Definition)

1、複雜元素:有子元素的元素

<!ELEMENT 元素名稱 (子元素)>

eg:
<!ELEMENT person (name,age)>      

2、簡單元素

<!ELEMENT 元素名稱 (#PCDATA)>
eg:
<!ELEMENT age (#PCDATA)>      

3、引入dtd檔案

<!DOCTYPE person SYSTEM "demo.dtd">
• 1      

示例

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE person SYSTEM "demo.dtd">
<person>
    <name>張三</name>
    <age>23</age>
</person>      

demo.dtd

<!ELEMENT person (name, age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>      

課時13 DTD的三種引入方式

1、引入外部

<!DOCTYPE 根元素名稱 SYSTEM "dtd路徑">      

2、引入内部

<!DOCTYPE 根元素名稱 [
        <!ELEMENT person (name, age)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT age (#PCDATA)>
]>      

3、使用網絡

<!DOCTYPE 根元素名稱 PUBLIC "DTD名稱" "DTD路徑URL">      

課時14 使用DTD定義元素

文法

<!ELEMENT 元素名 限制>      

1、簡單元素:沒有子元素的元素

<!ELEMENT 元素名 (#PCDATA)>      

(#PCDATA) 字元串(需要加括号)

EMPTY 元素為空

ANY 任意

2、複雜元素

<!ELEMENT 元素名 (子元素)>      

(1)子元素出現次數

+

 一次或多次

?

 零次或一次

*

 零次或多次

(2)子元素分隔符

逗号隔開:表示出現順序

豎線隔開:表示任意一個

eg:

<!ELEMENT person (name+, age?, sex, school*)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex EMPTY>
<!ELEMENT school ANY>      

課時15 使用DTD定義屬性

<! ATTLIST 元素名稱
    屬性名稱 屬性類型 屬性的限制
>      

1、屬性類型

(1)CDATA 字元串

(2)(a|b|c) 枚舉

(3)ID 值隻能以字母或下劃線開頭

2、屬性的限制

(1)#REQUIRED 屬性必須存在

(2)#IMPLIED 屬性可有可無

(3)#FIXED 屬性必須是固定值

(4)預設值 不寫屬性做為預設值

<!ATTLIST 頁面作者
    姓名 CDATA #REQUIRED
    年齡 CDATA #IMPLIED
    職位 CDATA #FIXED 作者
    愛好 CDATA 寫作
>      

課時16 定義實體

定義
<!ENTITY 實體名稱 "實體值">

使用
&實體名稱      

實體需要定義在内部dtd

課時17 W3C的案例

https://www.w3school.com.cn/dtd/dtd_examples.asp

第3 章: XML解析之JAXP

課時18 XML解析簡介

1、dom方式解析xml過程:

根據xml的層級結構,在記憶體中配置設定一個樹形結構

把xml中每部分都封裝成對象

(1)優點:友善實作增、删、改操作

(2)缺點:如果檔案過大,造成記憶體溢出

2、sax方式解析xml過程:

采用事件驅動,邊讀邊解析,從上到下,一行一行的解析,

解析到一個對象,把對象名稱傳回

(1)優點:不會造成記憶體溢出,實作查詢

(2)缺點:不能實作增、删、改操作

課時19 JAXP API的檢視

dom和sax解析器:

(1)sun公司 jaxp

(2)dom4j組織 dom4j(實際開發)

(3)jdom組織 jdom

1、jaxp

jaxp是javese一部分

javax.xml.parses

interface Node{
    // 添加節點
    public Node appendChild(Node newChild);

    // 移除節點
    public Node removeChild(Node oldChild);

    // 擷取父節點
    public Node getParentNode();

    // 傳回文本内容
    public String getTextContent()

}

interface NodeList{
    // 通過下标擷取具體值
    public Node item(int index);

    // 得到集合長度
    public int getLength();
}

interface Document extends Node{
    // 擷取标簽
    public NodeList getElementsByTagName(String tagname);

    // 建立标簽
    public Element createElement(String tagName);

    // 建立文本
    public Text createTextNode(String data);

}

abstract DocumentBuilder{
    public Document parse(File f)
}

abstract DocumentBuilderFactory{
    public static DocumentBuilderFactory newInstance()
    public abstract DocumentBuilder newDocumentBuilder()
}

abstract class SAXParser{}

abstract class SAXParserFactory{}      

課時20-21 使用JAXP查詢節點

示例:查詢xml中所有name值

demo.xml

<?xml version="1.0" encoding="utf-8" ?>
<list>
    <person>
        <name>張三</name>
        <age>23</age>
    </person>
    <person>
        <name>李四</name>
        <age>24</age>
    </person>
</list>      
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

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

public class Demo {
    /**
     * 1、建立解析器工廠
     * 2、根據解析器工廠建立解析器
     * 3、解析xml傳回document
     *
     */
    public static void main(String[] args) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        DocumentBuilder builder = factory.newDocumentBuilder();

        Document document = builder.parse("demo.xml");

        NodeList list = document.getElementsByTagName("name");

        for (int i = 0; i < list.getLength(); i++) {
            Node node = list.item(i);
            String name = node.getTextContent();
            System.out.println(name);
            // 張三 李四
        }
    }
}
      

課時22 使用JAXP添加節點

在person節點下添加sex子節點

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

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

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

public class Demo {

    public static void main(String[] args) throws Exception {
        // 建立解析器工廠
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        // 根據解析器工廠建立解析器
        DocumentBuilder builder = factory.newDocumentBuilder();

        // 解析xml傳回document
        Document document = builder.parse("demo.xml");

        NodeList list = document.getElementsByTagName("person");

        // 擷取第一個元素
        Node node = list.item(0);

        // 建立一個元素
        Element element = document.createElement("sex");
        Text text = document.createTextNode("女");

        // 添加建立的元素到節點
        element.appendChild(text);
        node.appendChild(element);

        // 回寫到硬碟
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.transform(new DOMSource(document), new StreamResult("demo.xml"));
    }
}
      

課時23-24 使用JAXP修改、删除節點

xml讀取和儲存的工具類

package util;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;

public class DocumentUtil {
    public static Document loadXml(String filename) throws ParserConfigurationException, IOException, SAXException {
        // 建立解析器工廠
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        // 根據解析器工廠建立解析器
        DocumentBuilder builder = factory.newDocumentBuilder();

        // 解析xml傳回document
        return builder.parse(filename);
    }

    public static void dumpXml(String filename, Document document) throws TransformerException {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.transform(new DOMSource(document), new StreamResult(filename));
    }
}
      
import org.w3c.dom.*;
import util.DocumentUtil;

public class Demo {

    public static void main(String[] args) throws Exception {
        String filename = "demo.xml";
        // 讀取
        Document document = DocumentUtil.loadXml(filename);

        // 查詢節點
        NodeList list = document.getElementsByTagName("name");
        Node node = list.item(0);

        // 設定節點内容
        node.setTextContent("大壯");

        // 删除節點
        Node parentNode = node.getParentNode();
        parentNode.removeChild(node);

        // 回寫到硬碟
        DocumentUtil.dumpXml(filename, document);
    }
}
      

課時25 使用JAXP周遊節點

使用遞歸周遊

import org.w3c.dom.*;
import util.DocumentUtil;

public class Demo {
    public static void listElement(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++) {
            listElement(list.item(i));
        }
    }

    public static void main(String[] args) throws Exception {
        String filename = "demo.xml";
        // 讀取
        Document document = DocumentUtil.loadXml(filename);

        listElement(document);
    }
}
      

第4 章 : Schema:基于XML的DTD替代者

課時26 Schema的介紹

dtd文法

<!ELEMENT 元素名稱 限制>      

scheme符合xml文法

一個xml可以有多個scheme,使用名稱空間區分

dtd有PCDAT類型scheme支援更多資料類型

scheme文法更加複雜

Schema 教程

https://www.w3school.com.cn/schema/index.asp

課時27 Schema的開發過程

*.xsd

1、屬性

<!-- 表示限制檔案 -->
xmlns="http://www.w3.org/2001/XMLSchema"

<!-- 限制檔案命名空間 url位址保證不會重複 -->
targetNamespace="http://www.w3school.com.cn"

<!-- 品質良好 -->
elementFormDefault="qualified"      
<complexType>
    <sequence>
        <element name="name" type="string"></element>
        <element name="age" type="int"></element>
    </sequence>
</complexType>      

3、引入限制文檔

表示被限制文檔,别名xsi
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

路徑位址
xsi:schemaLocation="http://www.w3school.com.cn demo.xsd">      

完整示例

demo.xsd

<?xml version="1.0" encoding="UTF-8" ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.w3school.com.cn"
        elementFormDefault="qualified">
    <element name="person">
        <complexType>
            <sequence>
                <element name="name" type="string"></element>
                <element name="age" type="int"></element>
            </sequence>
        </complexType>
    </element>
</schema>      

引入xsd檔案

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns="http://www.w3school.com.cn"
      xsi:schemaLocation="http://www.w3school.com.cn demo.xsd">
        <name>張三</name>
        <age>23</age>
</person>      

課時28 Schema限制API檢視

sequence 表示元素出現順序

all 隻能出現一次

choice 出現任意一個

maxOccurs=“unbounded” 出現次數沒有限制

any 任意元素

複雜元素中定義屬性

<attribute name="age" type="int" use="required"></attribute>      

引入多個schema,可以給每個schema取别名

課時29 sax解析的過程

dom 記憶體虛拟樹形結構

sax 事件驅動,邊讀邊解析

package org.xml.sax;

public class HandlerBase{
    public void startElement (String name, AttributeList attributes);
    public void characters (char ch[], int start, int length);
    public void endElement (String name);
}


package org.xml.sax.helpers;

public class DefaultHandler{
    public void startElement (String uri, String localName,
                              String qName, Attributes attributes)    

    public void endElement (String uri, String localName, String qName)
    public void characters (char ch[], int start, int length)
}

      

課時30 使用Schema的sax方式操作xml

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

<person> 
    <name>張三</name>  
    <age>23</age> 
</person>
      

使用jaxp的sax解析隻能進行查詢操作

import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

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

public class Demo {
    
    public static void main(String[] args) throws Exception {

        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();

        // 傳入事件處理類
        parser.parse("demo.xml", new MyDefaultHandler());

    }
}

/**
 * 自定義事件處理
 */
class MyDefaultHandler extends DefaultHandler {

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) {
        System.out.println(qName);
    }

    @Override
    public void endElement(String uri, String localName, String qName) {
        System.out.println(qName);
    }

    @Override
    public void characters(char[] ch, int start, int length) {
        System.out.println(new String(ch, start, length));
    }
}