XML

XML

概念:extensible markup language 可扩展标记语言
可扩展:标签都是自定义的。

功能:

? 存储数据,用来代替properties。
? java程序配置文件
? 在网络中传输

XML和HTML的区别

  1. xml 标签都是自定义的,html 是预定义的
  2. HTML是不区分大小写的,而XML是严格区分大小写的。
  3. HTML中,空格是自动过滤的,而XML中空格则不会自动删除。
  4. HTML被设计出是用来显示数据的,XML被设计出是为了传输和存储数据的。

语法

  1. 后缀名:.xml
  2. xml第一行必须是文档声明:<?xml version="1.0" encoding="UTF-8"?>
  3. xml文档中有且仅有一个根标签
  4. 属性值必须使用引号包起来
  5. 标签必须正确关闭

组成

  1. 文档声明:

    1. 格式:<?xml 属性列表?>
    2. 属性列表:
      • version版本号,必须有
      • encodeing编码方式。默认是utf-8
      • standalone是否独立:取值是yes或no
  2. 标签:标签名自定义

  3. 属性:id属性值唯一

  4. 文本:
    CDATA区:在该区域的数据会被原样展示,不需要使用转义字符了。

    <![CDATA[数据]]>
    

约束

约束:规定xml文档的书写格式。
使用框架时,程序员编写配置文件时必须按照框架提供的格式书写。所以框架会提供一个约束文档,程序员阅读约束文档后才能写出符合框架要求的xml文档。所以程序员使用框架必须:能够读懂约束文档,能够在xml文档中引入约束文档。
约束文档分类:

DTD

Document Type Definition:一种简单的约束技术
引入:将约束的规则定义在外部的dtd文件中,在xml中加入代码:
本地dtd:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
网络dtd:<!DOCTYPE 根标签名 PUBLIC "dtd文件名" "dtd文件的url">

标签 说明
<!ELEMENT> 定义xml文档中允许出现的节点及数量
<!ATTLIST> 定义xml文档中允许出现的属性

示例代码:

<!ELEMENT students (student*) ><!-- students根元素下允许出现任意数量的student元素。*代表任意数量、+代表至少一个、?代表最多一个-->
<!ELEMENT student (name,age,sex)><!-- student元素下必须出现name、age、sex元素,按顺序出现-->
<!ELEMENT name (#PCDATA)><!-- 此标签体只能是文本,#PCDATA代表文本元素-->
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST student number ID #REQUIRED>
<?xml version=‘1.0‘ encoding=‘utf-8‘ ?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
    <student number="s001">
        <name>zhangsan</name>
        <age>12</age>
        <sex>male</sex>
    </student>
    <student number="s002">
        <name>lisi</name>
        <age>15</age>
        <sex>male</sex>
    </student>
</students>

Schema

Schema:复杂的约束技术,可以结合枚举、正则表达式。Schema是W3C标准。
schema文件的后缀是: .xsd 。

<?xml version="1.0" encoding="utf-8" ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
    <element name="hr">
        <!-- complexType标签含义是复杂节点,包含子节点时必须使用这个标签-->
        <complexType>
		<!-- sequence里面的标签必须按照顺序严格编写-->
            <sequence>
                <element name="employee" minOccurs="1" maxOccurs="9999">
                    <complexType>
                        <sequence>
                            <element name="name" type="string"></element>
                            <element name="age" type="integer"></element>
                            <element name="salary" type="integer"></element>
                            <element name="department">
                                <complexType>
                                    <sequence>
                                        <element name="dname" type="string"></element>
                                        <element name="address" type="string"></element>
                                    </sequence>
                                </complexType>
                            </element>
                        </sequence>
                        <attribute name="no" type="string" use="required"></attribute>
                    </complexType>
                </element>
            </sequence>
        </complexType>
    </element>
</schema>

编写xml:

<?xml version="1.0" encoding="utf-8" ?>
<hr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:NoNamespaceLocaion="hr.xsd">
    <!-- 人力资源管理系统 -->
    <employee no="0001">
        <name>张三</name>
        <age>20</age>
        <salary>5000</salary>
        <department>
            <dname>公关部</dname>
            <address>北京大厦1201室</address>
        </department>
    </employee>
    <employee no="0002">
        <name>李四</name>
        <age>21</age>
        <salary>10000</salary>
        <department>
            <dname>后勤部</dname>
            <address>北京大厦1202室</address>
        </department>
    </employee>
</hr>

解析

解析:操作xml文档,将其中的内容读取到内存中
解析xml的方式

  • DOM:将标记语言文档一次性加载到内存中,在内存中形成一颗DOM树。优点:操作方便,增删改查都可以。缺点:占内存。
  • SAX:逐行读取,基于事件驱动的。优点:不占内存。缺点:只能读取,不能增删改。

常见xml解析器:

  1. AXP:sun公司提供的解析器,支持dom和sax两种思想。没人用
  2. DOM4J:一款非常优秀的解析器,基于SAX
  3. Jsoup:jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

Jsoup快速入门

  1. 导入jar包
  2. 获取Document对象
  3. 获取对应的Element对象
  4. 获取数据

对象的使用

  1. Jsoup工具类:解析html或xml文档,返回Document

    方法 描述
    parse(File in, String charsetName) 以指定的字符集解析xml文档
    parse(String html) 解析xml或html字符串
    parse(URL url, int timeoutMillis) 通过网络路径获取指定的html或xml的文档对象
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.select.Elements;
    
    import java.io.File;
    import java.io.IOException;
    
    public class JsoupDemo2 {
        public static void main(String[] args) throws IOException {
    //        //parse(URL url, int timeoutMillis)
    //        URL url = new URL("https://www.baidu.com");
    //        Document baidu = Jsoup.parse(url,5000);
    //        System.out.println(baidu);
    
            //parse(File in, String charsetName)
            String path = JsoupDemo2.class.getClassLoader().getResource("student.xml").getPath();
            Document document = Jsoup.parse(new File(path), "utf-8");
            Elements names = document.getElementsByTag("name");
            System.out.println(names);
    
    //        //parse(String html)
    //        String str = "<html>\n" +
    //                "<head>\n" +
    //                "<title>百度</title>\n" +
    //                "</head>\n" +
    //                "<body>\n" +
    //                "</body>\n" +
    //                "</html>";
    //        Document htmlDoc = Jsoup.parse(str);
    //        System.out.println(htmlDoc);
        }
    }
    
    
  2. Document文档对象:代表内存中的DOM树
    获取Element对象

    方法 描述
    getElementById(String id) 根据id属性值获取唯一的element对象
    getElementsByTag(String tagName) 根据标签名称获取元素对象集合
    getElementsByAttribute(String key) 根据属性名称获取元素对象集合
    getElementsByAttributeValue(String key, String value) 根据对应的属性名和属性值获取元素对象集合
  3. Elements:元素Element对象的集合,可以当做ArrayList<Element>来使用

  4. Element

    1. 获取子元素对象

      方法 描述
      getElementById(String id) 根据id属性值获取唯一的element对象
      getElementsByTag(String tagName) 根据标签名称获取元素对象集合
      getElementsByAttribute(String key) 根据属性名称获取元素对象集合
      getElementsByAttributeValue(String key, String value) 根据对应的属性名和属性值获取元素对象集合
    2. 获取属性值
      String attr(String key): 根据属性名获取属性值

    3. 获取文本内容
      String text():获取标签体内部的纯文本内容(不含标签)
      String html():以html文档的形式获取标签体的文本内容(含标签)

      public class JsoupDemo4 {
          public static void main(String[] args) throws IOException {
              //获取document对象
              String path = JsoupDemo4.class.getClassLoader().getResource("student.xml").getPath();
              Document document = Jsoup.parse(new File(path),"utf-8");
              //获取name对象的集合
              Elements stus = document.getElementsByTag("student");
              System.out.println(stus.size());//2
              System.out.println("--------");
              //获取第一个name对象
              Element student = stus.get(0);
              System.out.println(student.text());//tom 18 male
              System.out.println(student.html());//完整的html文档
      
          }
      }
      
      
  5. Node:节点对象

Dom4快速入门

自己搜索Dom4j下载jar包并导入

package com.imooc;

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

import javax.xml.transform.sax.SAXResult;
import java.util.List;

/**
 * @author shenguopin
 * @date 2021/8/24 17:23
 */
public class Dom4jTest {
    public static void main(String[] args) {
        String path = Dom4jTest.class.getClassLoader().getResource("hr_schema.xml").getPath();
       
        //SAXReader是读取xml的核心类,用于将xml解析后以树的形式保存在内存中
        SAXReader reader = new SAXReader();
        
        try {
            Document document = reader.read(path);
            //获取xml文档的根节点,即hr标签
            Element root = document.getRootElement();
            //通过根节点获取子元素数组,使用elements方法
            List<Element> employees = root.elements("employee");
            for (Element employee : employees) {
                //获取属性
                Attribute no = employee.attribute("no");
                System.out.println(no.getText());

                //element方法获取唯一子元素
                Element name = employee.element("name");
                String nameText = name.getText();
                System.out.println(nameText);
                System.out.println(employee.elementText("age"));
                System.out.println(employee.elementText("salary"));

                Element department = employee.element("department");
                System.out.println(department.elementText("dname"));
                System.out.println(department.elementText("address"));

                System.out.println("*********************************");
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}

XPath

快捷查询方式:
使用元素对象一般是一层一层的查询,如果层级比较多就很慢。下面有两种快速的查询方式,可以精确的定位到想要的元素。

  1. selector选择器
    Elements select(String cssQuery);参考java.lang.Selector使用

    public class JsoupDemo5 {
        public static void main(String[] args) throws IOException {
            //获取document对象
            String path = JsoupDemo5.class.getClassLoader().getResource("student.xml").getPath();
            Document document = Jsoup.parse(new File(path),"utf-8");
    
            //使用selector选择器
            //获取student标签并且number属性值为heima_0001的age子标签
            Elements elements = document.select("student[number="heima_0002"] > age");
            System.out.println(elements);
    
        }
    }
    
    
  2. XPath:XPath即为XML路径语言,来自W3C,具体用法见w3school的xpath文档
    使用Jsoup的Xpath需要额外导入jar包。

    public class JsoupDemo6 {
        public static void main(String[] args) throws IOException, XpathSyntaxErrorException {
            //1.获取student.xml的path
            String path = JsoupDemo6.class.getClassLoader().getResource("student.xml").getPath();
            //2.获取Document对象
            Document document = Jsoup.parse(new File(path), "utf-8");
    
            //3.根据document对象,创建JXDocument对象
            JXDocument jxDocument = new JXDocument(document);
    
            //4.结合xpath语法查询
            //4.1查询所有student标签
            List<JXNode> jxNodes = jxDocument.selN("//student");
            for (JXNode jxNode : jxNodes) {
                System.out.println(jxNode);
            }
    
            System.out.println("--------------------");
    
            //4.2查询所有student标签下的name标签
            List<JXNode> jxNodes2 = jxDocument.selN("//student/name");
            for (JXNode jxNode : jxNodes2) {
                System.out.println(jxNode);
            }
    
            System.out.println("--------------------");
    
            //4.3查询student标签下带有id属性的name标签
            List<JXNode> jxNodes3 = jxDocument.selN("//student/name[@id]");
            for (JXNode jxNode : jxNodes3) {
                System.out.println(jxNode);
            }
            System.out.println("--------------------");
            //4.4查询student标签下带有id属性的name标签 并且id属性值为itcast
    
            List<JXNode> jxNodes4 = jxDocument.selN("//student/name[@id=‘itcast‘]");
            for (JXNode jxNode : jxNodes4) {
                System.out.println(jxNode);
            }
        }
    
    }
    

XML

上一篇:Leetcode - 13. 罗马数字转整数


下一篇:C的32个关键字