XML

一、基本概念

1、基础概念

  XML可扩展标记语言。
  可扩展:标签都是自定义的。

2、XML功能

  XML的主要功能是用来存储数据,主要用来存储:
  1、配置文件;
  2、在网路中进行数据传输。
  3、XML和HTML的区别:
    ①、XML标签都是自定义的,而HTML的标签是预定义的;
    ②、XML语法严格,HTML语法较为松散;
    ③、XML是用来存储数据的,HTML是用来展示数据的。

二、语法

1、快速入门XML基本语法

  首先新建一个文本文档然后保存后缀名为‘.xml’的文件格式,用文本编辑软件打开,进行编写保存;
  用浏览器打开,发现没有出现错误说明,书写正确。下面是编写的一个示例demo。
<?xml version='1.0' ?>
<users>
    <user id='1'>
        <name>zhangsan</name>
        <age>23</age>
        <gender>male</gender>
    </user>
</users>
  注意总结:
    ①、第一行要有文档声明,即使前面加空白行也不行;
    ②、有且仅有一个根标签;
    ③、后缀必须是‘.xml’;
    ④、可以定义自闭合的标签,标签必须有结束标签,必须要正确关闭;
    ⑤、属性值必须要使用引号(单双引号均可)引起来;
    ⑥、标签区分大小写。

2、语法组成部分

  2.1文档声明
    1.格式:<?xml 属性列表 ?>
    2.属性列表:
      version:版本号,必须要有的属性;
      encoding:编码格式,告诉解析引擎使用什么编码方法解析该文档,不写默认的是ISO-8859-1;
      standalone:是否独立,取值为yes/no了解即可。
  2.2指令
    由于XML早期是为了解觉HTML浏览器恶性竞争带来的问题,所以XML也有数据的展示功能。结合CSS一起使用:
<?xml-stylesheet type="text/css" href="CSS样式" ?>
  2.3标签
    名称:自定义;
    规则:
      1、数字和字符不能开头;
      2、不能以XML(不管大小写都不行)开始;
      3、不能包含空格。
  2.4属性
    id属性值唯一。
  2.5文本
    特殊字符需要转义;
      &:&amp;
      <:&lt;
      >:&gt;
    CDATA区:在该区域中的内容会被原样展示;
    格式:<![CDATA[要展示的数据]]>

 3、约束

  3.1.基本概念
    约束:规定XML文档的书写规则;
    
    作为框架的使用人员:
      1、能够在XML中引入约束文档;
      2、能够简单的读懂约束文档。
  3.2.分类
    1、DTD技术
      一种简单的约束技术,无法对属性的内容进行限定;
      引入dtd文档到XML文档中:
        1.内部引入:将约束规则定义在XML文档内部;
        2.外部引入:将约束规则定义在XML文档外部得到dtd后缀的文件中。
          ①、本地:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
<文件名:student.dtd>==============
<!ELEMENT students (student*) >
        <!--使用ELEMENT,来定义属性-->
        <!--students标签的子标签student标签,能够出现*表示多次-->
<!ELEMENT student (name,age,sex) >
        <!--表示student标签能够按照顺序放括号中的值-->
<!ELEMENT name (#PCDATA) >
        <!--PCDATA表示字符串-->
<!ELEMENT age (#PCDATA) >
<!ELEMENT sex (#PCDATA) >
<!ATTLIST student number ID #REQUIRED >
        <!--使用ATTLIST,来定义标签-->
        <!--student标签有一个number属性,属性的类型是ID-->
        <!--REQUIRED表示必须出现-->
        
<文件名:student.xml>==============
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "student.dtd">
        <!--引入DTD格式文档-->
        <!--为本地外部引入方式-->
<students>
    <student number="jzb_0001">
        <name>tom</name>
        <age>18</age>
        <sex>male</sex>
    </student>
</students>
           直接在XML中声明则是:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students [
        <!ELEMENT students (student*) >
        <!ELEMENT student (name,age,sex) >
        <!ELEMENT name (#PCDATA) >
        <!ELEMENT age (#PCDATA) >
        <!ELEMENT sex (#PCDATA) >
        <!ATTLIST student number ID #REQUIRED >
        ]>
<students>
    <student number="jzb_0001">
        <name>tom</name>
        <age>18</age>
        <sex>male</sex>
    </student>
</students>
          ②、网络:<!DOCTYPE 根标签名 PUBLIC "dtd的位置URL">
     2、schema技术
        一种复杂的约束技术;

三、XML解析

  解析:操作XML文档,将文档内的数据读取到内存中。

1、操作XML文档

  1.解析(读取):将文档中的数据读取到内存中;
  2.写入(保存):将内存中的数据用XML进行保存,实现数据的持久化。

2、数据解析方式

  1.DOM方式:将整个标记语言一次性加载进入内存,在内存中形成一颗DOM树。
    优点:操作方便,能够进行CRUD的所有操作。
    缺点:所有内容直接加进内存,比较占用内存。
  2.SAX方式:一行一行进行读取,就会面临读过之后就会释放的问题,所以该方式使用的是事件进行驱动。
    优点:逐行进行读取,不占用内存。
    缺点:只能读取,不能进行CRUD。

  3.两种方式比较:

    两种方式的特性决定了他们使用的地方不同,DOM解析方式一般在服务器端进行使用,而SAX一般解析客户端的内容。

3、XML常见的解析器

  1.JAXP:SUN公司提供的解析器,支持DOM和SAX两种解析方式;
  2.DOM4j:一款优秀的解析软件;
  3.Jsoup:是一款 解析HTML的解析器提供了方便的API,通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据;
  4.PULL:Android操作系统内置解析器,是SAX解析方式。

4、使用Jsoup

  快速使用:
    ①导入jar包到工程里面;
    ②获取document对象;
    ③获取对应的标签(Element对象);
    ④获取数据。
package cn.jzb.xml.jsoup;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;

/*
* Jsoup快速入门
* */
public class JsoupDemo1 {
    public static void main(String[] args) throws IOException {
        /*1.导入相应的jar包*/
        /*2.获取document对象*/
        //方式一:根据XML文档获取
            //获取student.xml的path
        String path = JsoupDemo1.class.getClassLoader().getResource("student.xml").getPath();
             //解析XML文档,加载文档进内存,获取DOM树--->Document
        Document document = Jsoup.parse(new File(path), "utf-8");
            //获取元素对象Element
        Elements elements = document.getElementsByTag("name");
        System.out.println(elements .size());/*在XML文件中有2个,说明上面的是元素的集合*/
            //获取第一个name的Element对象
        Element element = elements.get(0);
            //获取数据
        String name = element.text();
        System.out.println(name);
    }
}

5、Jsoup对象的使用

  1、Jsoup工具类:可以解析HTML和XML文档,返回Document。
    parse:解析HTML或者XML文档,返回Document;
    1、parse​(File in, String charsetName):解析XML或HTML文件
    2、parse​(String html):解析XML或HTML字符串;
    3、parse​(URL url, int timeoutMillis) :通过网络路径获取指定的HTML或XML的文档对象。
package cn.jzb.xml.jsoup;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;


import java.io.IOException;
import java.net.URL;

/*
* Jsoup对象功能
* */
public class JsoupDemo2 {
    public static void main(String[] args) throws IOException {
        String path = JsoupDemo2.class.getClassLoader().getResource("student.xml").getPath();
        /*第一种方式:parse​(File in, String charsetName)*/
        /*Document document = Jsoup.parse(new File(path), "utf-8");
        System.out.println(document);*/

        /*第二种方式:parse​(String html)*/
        /*String str ="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
                "\n" +
                "<students>\n" +
                "\t<student number=\"heima_0001\">\n" +
                "\t\t<name>tom</name>\n" +
                "\t\t<age>18</age>\n" +
                "\t\t<sex>male</sex>\n" +
                "\t</student>\n" +
                "\t<student number=\"heima_0002\">\n" +
                "\t\t<name>Jack</name>\n" +
                "\t\t<age>23</age>\n" +
                "\t\t<sex>female</sex>\n" +
                "\t</student>\n" +
                "\n" +
                "</students>";
        Document document = Jsoup.parse(str);
        System.out.println(document);*/

        /*第三种方式:parse​(URL url, int timeoutMillis)*/
        URL url = new URL("https://www.baidu.com");
        Document document = Jsoup.parse(url, 100000);
    }
}
  2、Document:文档对象,代表内存中的DOM。
    getElementsByTag​(String tagName):根据标签名获取元素对象集合;
    getElementsByAttribute​(String key):根据属性名获取元素对象集合;
    getElementsByAttributeValue​(String key, String value):根据属性名和属性值获取元素对象集合。
    getElementById​(String id):根据id属性值获取唯一的element对象。
package cn.jzb.xml.jsoup;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;
import java.net.URL;

/*
* Element对象的子对象Document对象功能
* */
public class JsoupDemo3 {
    public static void main(String[] args) throws IOException {
        String path = JsoupDemo3.class.getClassLoader().getResource("student.xml").getPath();
        Document document = Jsoup.parse(new File(path),"utf-8");
        //获取所有student对象
        Elements elements = document.getElementsByTag("student");
        System.out.println(elements);
        System.out.println("=============================");
        //获取属性名为id的元素对象们
        Elements elements1 = document.getElementsByAttribute("id");
        System.out.println(elements1);
        System.out.println("=============================");
        //获取number属性值为jzb_0001的元素对象
        Elements elements2 = document.getElementsByAttributeValue("number", "jzb_0001");
        System.out.println(elements2);
        System.out.println("=============================");
        //根据id来获得属性值
        Element byId = document.getElementById("zhang");
        System.out.println(byId);
    }
}
  3、Elements:元素Element对象的集合,可以当做ArrayList<Element>来使用。
  4、Element:元素对象。
    1.获取子元素对象
      getElementsByTag​(String tagName):根据标签名获取元素对象集合;
      getElementsByAttribute​(String key):根据属性名获取元素对象集合;
      getElementsByAttributeValue​(String key, String value):根据属性名和属性值获取元素对象集合。
      getElementById​(String id):根据id属性值获取唯一的element对象。
    2.获取属性值
      String attr​(String attributeKey):根据属性名称获取属性值
    3.获取文本内容
      String text():获取所有子标签的纯文本内容,不包含子标签;
      String html():获取标签体内所有的内容,包括子标签也会一并获取到;
package cn.jzb.xml.jsoup;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;

/*
* Element对象功能
* */
public class JsoupDemo4 {
    public static void main(String[] args) throws IOException {
        String path = JsoupDemo4.class.getClassLoader().getResource("student.xml").getPath();
        Document document = Jsoup.parse(new File(path),"utf-8");
        //通过Element对象获取其子对象的元素标签name
        Element element_student = document.getElementsByTag("student").get(0);
        Elements ele_name = element_student.getElementsByTag("name");
        System.out.println(ele_name.size());
        System.out.println("=============================");
        //获取student对象的属性值
        String number = element_student.attr("number");//不区分大小写
        System.out.println(number);
        System.out.println("=============================");
        //获取文本内容
        String text = ele_name.text();
        System.out.println(text);
        System.out.println("=============================");
        String html = ele_name.html();
        System.out.println(html);
        System.out.println("=============================");
    }
}
  5、Node:节点对象。
     Document和Element的父类;

6、快捷的查询方式

  可以不用像之前的那样,一级一级标签进行获取,使用选择器,不记得的可以查阅文档,下载Jsoupdoc.jar然后解压,找到index页面打开,查找能找到具体的使用方法。下面截图:

  

   

  1、select:选择器
    使用方法:Elements select​(String cssquery)
    在cssquery中使用选择器,下面是使用的实例:
package cn.jzb.xml.jsoup;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;

/*
* 选择器查询
* */
public class JsoupDemo5 {
    public static void main(String[] args) throws IOException {
        String path = JsoupDemo5.class.getClassLoader().getResource("student.xml").getPath();
        Document document = Jsoup.parse(new File(path),"utf-8");

        //查询name标签
        Elements elements = document.select("name");
        System.out.println(elements);
        System.out.println("-=============================");
        //查询id值为zhang的元素
        Elements elements1 = document.select("#zhang");
        System.out.println(elements1);
        System.out.println("=============================");
        //案例:获取student标签并且number属性值为jzb_0001的age子标签
            //1.获取tudent标签并且number属性值为jzb_0001
        Elements elements2 = document.select("student[number='jzb_0001']");
        System.out.println(elements2);
        System.out.println("=============================");
            //2.获取elements2的age子标签
        Elements elements3 =document.select("student[number='jzb_0001'] > age");
        System.out.println(elements3);
    }
}
  2、XPath
    XPath即为XML路径语言,它是一种用来确定XML文档中某部分位置的语言。
    第一步:导如Xpath的jar包,下面是下载地址:
      https://javalibs.com/artifact/cn.wanghaomiao/JsoupXpath
    第二步:参考W3Cschool参考手册的语法部分完成查询,下面是参考手册的地址。
      https://www.w3school.com.cn/xpath/xpath_syntax.asp
package cn.jzb.xml.jsoup;

import cn.wanghaomiao.xpath.exception.XpathSyntaxErrorException;
import cn.wanghaomiao.xpath.model.JXDocument;
import cn.wanghaomiao.xpath.model.JXNode;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;


import java.io.File;
import java.io.IOException;
import java.util.List;


/*
* XPath查询
* */
public class JsoupDemo6 {
    public static void main(String[] args) throws IOException, XpathSyntaxErrorException {
        String path = JsoupDemo6.class.getClassLoader().getResource("student.xml").getPath();
        Document document = Jsoup.parse(new File(path),"utf-8");

        //根据document对象创建JXDocument对象
        JXDocument jxDocument = new JXDocument(document);
        //1.查询所有student标签
        List<JXNode> jxNodes1 = jxDocument.selN("//student");
        for (JXNode jxNode : jxNodes1) {
            System.out.println(jxNode);
            System.out.println(jxNode.getElement());
        }
        System.out.println("=============================");
        //2.查询所有student标签下的name标签
        List<JXNode> jxNodes2 = jxDocument.selN("//student/name");
        for (JXNode jxNode : jxNodes2) {
            System.out.println(jxNode);
            System.out.println(jxNode.getElement());
        }
        System.out.println("=============================");
        //3.查询student标签下带id的name标签
        List<JXNode> jxNodes3 = jxDocument.selN("//student/name[@id]");
        for (JXNode jxNode : jxNodes3) {
            System.out.println(jxNode);
        }
        System.out.println("=============================");
        //4.查询student标签下带有id的值为zhang的name标签
        List<JXNode> jxNodes4 = jxDocument.selN("//student/name[@id='zhang']");
        for (JXNode jxNode : jxNodes4) {
            System.out.println(jxNode);
        }
        System.out.println("=============================");
     }
}

 

 

posted @ 2020-09-08 14:18  利兵秣码  阅读(281)  评论(0)    收藏  举报