天天看點

XML 解析XML文檔 XML限制XML

XML

什麼是XML

  1. Extensible Markup Language(可擴充的标記語言)
  2. 他是一個語言,有自己的文法,和Java以及其他的程式設計無關
  3. “标記” 在檔案中包含類似于張三 ,這種用尖括号括起來的叫标記,使用來标記資料的。标記可以嵌套,有包含、所屬關系。XML是純文字文檔,它是由“标記+資料”組成
  4. 例如:
    1. 建立檔案:clases.xml

      <類庫>

      <屬性>
      
      </ 屬性>
                 
      < /類庫>

XML 的作用

  1. 存儲資料【以後資料庫存儲檔案】
XML 解析XML文檔 XML限制XML
  1. 做配置檔案【重點應用方式】
XML 解析XML文檔 XML限制XML

XML的文法

1、文檔聲明

  1. 一個格式化好的XML文檔,應該有一個“文檔聲明”,不是必須有
  2. 文檔聲明格式:

2、XML的文法_元素(标簽)

  1. 元素:也叫标記、标簽。
  2. 标簽分類
    1. 完整标簽:有開始标簽,和結束标簽

      <name>張三</name>

    2. 單标簽:隻有開始标簽,沒有結束标簽;單标簽可以通過屬性來記錄資料

      <property name="id" value="it001"/>

  3. 标簽的文法
    1. 标簽名稱可以包含大部分的字元,包括中文
    2. 标簽裡可以包括以下的符号:“、 _ - . ”
    3. 但隻能以字母、下劃線、冒号開頭
    4. 标簽的内容:
      1. 可以是“資料”

        <name>張三</name>

      2. 可以是子标簽
        XML 解析XML文檔 XML限制XML
    5. 區分大小寫

3、屬性:唯一的

  1. 一個标簽中可以定義任意多個的“屬性”,屬性的作用:存儲資料。
  2. 文法規則
    1. 一個标簽可以定義0或者多個屬性,屬性名不能重名,用空格隔開
    2. 屬性的格式:屬性名=“屬性值”屬性值必須要用單引号或者雙引号括起來

      (認為單引号或者雙引号裡的内容是數值)

      XML 解析XML文檔 XML限制XML
    3. 屬性,必須定義在開始标簽中。

4、注釋

5、轉義字元

XML 解析XML文檔 XML限制XML

如果資料中包含大量的轉義字元,編寫時可讀性不好。可以使用CDATA區來标志資料。

XML 解析XML文檔 XML限制XML

6、解析XML文檔 兩種方式

  1. DOM解析:一次性将整個文檔讀取到記憶體中,會将内部的各種标簽已經屬性、資料等資訊全部封裝到一個對象中。最終形成DOM對象,在DOM對象内容保留文檔的結構資訊。優點:記憶體中保留文檔的結構進行修改(增加、修改、删除元素等修改)。缺點:如果文檔很大,會占用記憶體。
  2. SAX解析:一次讀取,解析一行,讀取下一行,之前的資訊會被丢掉。優點:速度快,缺點:沒有文檔結構,不能進行節點的增删改查。
  3. PULL解析:用于Android系統内容不的解析方式。類型于SAX。

7、解析器

  1. JAXP
  2. JDom
  3. Jsoup
  4. dom4j:第三方開發包,内部結合了DOM和SAX解析的方式

8、解析原理 是一個建立樹的過程

XML文檔讀取到記憶體的過程:先建立一個DOM對象(Document);在建立一個節點Element(根元素)對象;建立子元素Element(節點)對象在根元素下面;建立屬性(Attribute)對象在子節點對象下面;值(一般是String)對象在屬性對象下面;

Document
     |--根元素【Element】
        |--子元素
            |--屬性對象【Attribute】
                |--值對象
            |--子元素對象(Element)
                |--值對象
                |--子元素對象
           

9、XML文檔讀取步驟

準備工作:引入第三方工具包Dom4j.jar

  1. 建立SAXReader對象
  2. 對象對去XML文檔,生成DOM樹
  3. 擷取根元素
  4. 擷取到根元素後,利用它獲得其他的子元素還有它自己在的屬性(Attribute)

常用的方法:

1.public String getName():擷取目前Element對象的”标簽名”;

2.public List elements():擷取目前Element對象下的所有子元素;

3.public List elements(String eleName):擷取目前Element對象下的所有 eleName的子元素;

4.public String getText():擷取目前Element對象的資料内容;

5.public String elementText(String eleName):擷取目前Element對象的”eleName子元素的資料内容”;

代碼練習

demo.xml

<?xml version="1.0" encoding="UTF-8"?>
<students>
            <student id = "it001">
                <name>章子怡</name>
                <age>18</age>
                <sex>女</sex>
            </student>
            <student id = "it002">
                <name>汪峰</name>
                <age>19</age>
                <sex>男</sex>
            </student>
            <student id = "it003">
                <name>撒貝甯</name>
                <age>20</age>
                <sex>男</sex>
            </student>

            <teacher id="001" name="teacher">
                <name>春春</name>
                <age>56</age>
                <sex>女</sex>
            </teacher>

            <teacher>
            </teacher>
</students>
           

MyVisitor.java

import org.dom4j.Attribute;
import org.dom4j.Element;
import org.dom4j.VisitorSupport;

public class MyVisitor extends VisitorSupport {

    //擷取标簽的對象的名字
    @Override 
    public void visit(Element e) {

        System.out.println(e.getName());
    }
    //擷取标簽屬性的名字
    @Override
    public void visit(Attribute a) {
        System.out.println(a.getName());
    }
}
           

測試類 demo01.java

import java.io.File;

import java.util.Iterator;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * 解析demo.xml文檔
 * 
 * @author YandeHu
 *
 */
public class Demo01 {

    private static final String Element = null;

    public static void main(String[] args) throws Exception {
        // 建立SAXreader對象
        SAXReader reader = new SAXReader();
        // 讀取demo.xml文檔 傳回一個文檔對象
        Document dom = reader.read(new File("demo.xml"));
        // 讀取XML文檔的根節點
        Element root = dom.getRootElement();
        // 獲得根節點的名稱
        String rootName = root.getName();
        System.out.println(rootName);
        // 利用根節點獲得下面的子節點
        /**
         * 周遊子節點的兩種方式
         */
        // 疊代器周遊子節點

        Iterator elr = root.elementIterator();// 周遊所有的子節點還可以周遊
        while (elr.hasNext()) {
            Element e = (Element) elr.next();
            String id = e.attributeValue("id");// 擷取标簽的屬性值
            System.out.println("id=" + id);
            String age = e.elementText("age");// 擷取标簽<age>裡的内容
            System.out.println("age=" + age);
            System.out.println(e.getName());// 擷取節點的名字
            // System.out.println(e.getStringValue());//擷取标簽标記的資料
            System.out.println(e.getText());
        }

        /**
         * Visitor 是 GOF 設計模式之一。其主要原理就 是兩種類互相保有對方的引用,并且一種作為 Visitor 去通路許多
         * Visitable。
         */
        System.out.println("=========Visitor==============");
        root.accept(new MyVisitor());

    }
}
           

10、XML限制

  1. DTD:對一些簡單的XML檔案進行限制
  2. Schema:對一些比較複雜的XML文檔進行更加細緻、廣泛的限制。

XML限制可以限制:

  • 根元素下都可以出現哪些子元素
  • 元素出現的順序、次數
  • 元素包含的屬性
  • 元素中包含哪些子元素或者資料

DTD限制條件的引入

  1. 内部引入
    XML 解析XML文檔 XML限制XML
  2. 引入外部(本地)
  3. 引入外部(網絡)

Schema限制條件的引入

XML 解析XML文檔 XML限制XML

schema文檔結構說明

XML 解析XML文檔 XML限制XML

練習:讀取XML檔案擷取類的資訊,利用反射建立對象

代碼

student.xml

<?xml version="1.0" encoding="UTF-8"?>
<classes>
    <class className="com.day16.text.Student">
        <name>張三</name>
        <age>18</age>
    </class>
</classes>
           

Student類

public class Student {

    private String name;
    private int age;

    public Student() {
        super();
    }

    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }

}
           

RefiectDemo類 測試類

import java.io.File;
import java.lang.reflect.Constructor;
import java.util.Iterator;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ReflectDemo {

    public static void main(String[] args) throws Exception {
        //編寫方法 擷取XML文檔classname内容的方法 
        String s=getDom(new File("student.xml"));

        //利用反射建立執行個體
        Class<?> c = Class.forName(s);
        //擷取類的構造方法
        Constructor<?> con = c.getConstructor(String.class,int.class);
        Object stu = con.newInstance("小明",23);
        System.out.println(stu);
    }

    public static String getDom(File file) throws Exception{
        //建立SAXreader對象
        SAXReader reader=new SAXReader();
        //讀取XML文檔
        Document dom = reader.read(file);
        //擷取根節點
        Element root = dom.getRootElement();

        String value=null;
        //周遊根節點
        Iterator list = root.elementIterator();
        while(list.hasNext()){
            Element element = (Element) list.next();
            //擷取<class>标簽的屬性值
            Attribute classname= element.attribute("className");
            value= classname.getValue();
        }

        return value;
    }
}
           

2017/11/1 17:32:39