XML:可扩展标记语言

XML:可扩展标记语言

主要内容

  • XML介绍
  • DTD
  • XSD
  • DOM解析
  • SAX解析

学习目标

知识点 要求
XML介绍 掌握
DTD 掌握
XSD 掌握
DOM解析 掌握
SAX解析 掌握

一、XML介绍

1. 简介

XML(Extensible Markup Language)可扩展标记语言。严格区分大小写。

2. XML和HTML

XML是用来传输和存储数据的。

XML 多用在框架的配置文件中。

XML 大多平台都支持,所以可以实现跨平台数据传输。

HTML 是用来显示数据的。

3. 语法

<元素名 属性名=”属性值”>文本内容

前后元素名相同, 元素名自定义。

每个元素可以有0到多个属性,属性名自定义。

文本内容表示文字。

支持嵌套结构。

结束时元素名前有 /。

4. 语法要求

XML的语法和HTML语法是差不多的,但是比HTML要求更加严格。

​ 1. 元素正确嵌套

​ 2. XML文件的第一行必须是xml声明

​ 3. 只能有一个根节点

​ 4. 严格区分大小写

​ 5. 结束标签必须包含/

​ 6. 属性值必须被""包围起来

​ 7. XML认为换行标记也属于文本节点

​ 8. 注释。有的非官方资料认为这是注释节点。

XML:可扩展标记语言_第1张图片

5. 特殊字符

5.1 实体符号
XML:可扩展标记语言_第2张图片
5.2 转义标签

要显示的字符

]]>

XML:可扩展标记语言_第3张图片

二、小节实战案例 - 编写XML文件

1. 需求

项目根路径下创建product.xml并存储下面信息。

根节点叫做products,里面包含3个product元素。每个元素里面又包含下面的元素及文本内容

id 名称(name) 单价(price) 颜色(color) 尺寸(size) 库存(num)
P001 蜘蛛王皮鞋 268 黑色 42 500
P002 ThinkPad x240 5678 黑色 12 50
P003 WD移动硬盘 568 蓝色 5 1000

2. 实现

 
<products>
  <product>
    <id>P001id>
    <name>蜘蛛王皮鞋name>
    <price>268price>
    <color>黑色color>
    <size>42size>
    <num>500num>
  product>
  
products>

三、DTD

1. 简介

DTD(Document Type Definition)文档类型定义。

即约束XML文件中可以包含哪些元素、哪些属性、及元素个数和元素之间的关系和元素的顺序。

在包含DTD的XML文件中,如果XML内容不满足DTD要求,会提示错误。

2. 分类

DTD的三种分类:

​ 1. 内部DTD

​ 2. 外部DTD

​ 3. 公共DTD

2.1 内部DTD

直接在XML中编写DTD内容。不推荐。

  1. 内容可以是其他标签,也可以是#PCDATA文本内容。

  2. 定义属性

  3. 内容控制可取值:

​ 1. #REQUIRED 必须有这个属性

​ 2. #IMPLIED 可以有也可以没有

​ 3. #FIXED “内容” 必须取固定值

  1. (name,age,score) 表示顺序必须是先name,后age,然后score

  2. student+ 表示student至少出现一次。括号内容的元素名都可以跟下面符号

​ 1. ?表示子元素出现0次到1次 (最多出现一次)

​ 2. + 表示子元素至少出现一次 (至少出现一次 )

​ 3. *表示子元素可以出现0到多次 (任意)

 


DOCTYPE students[
        
        
        <!ELEMENT students (student*)>
        <!ELEMENT student (name, age, sex)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT age (#PCDATA)>
        <!ELEMENT sex (#PCDATA)>
        
        
        <!ATTLIST student id CDATA #REQUIRED>
        <!ATTLIST name class CDATA #FIXED "qwe">
        <!ATTLIST age test CDATA #IMPLIED>
        ]>

<students>
  <student id="aa">
    <name class="qwe">张三name>
    <age test="aaa">18age>
    <sex>sex>
  student>
students>
2.2 外部DTD

外部DTD是我们自己编写的DTD文件。通过引入方式引入DTD。

在外部创建一个xxx.dtd文件,文件内容和内部dtd [ ] 中的内容相同。

  1. 新建dtd文件








  1. xml引入外部dtd文件

DOCTYPE students SYSTEM "aa.dtd">
<students>
  <student id="aa" >
    <name class="qwe">张三name>
    <age test="aaa">18age>
    <sex>sex>
  student>
students>
2.3 公共DTD

公共DTD是一些开源组织编写的DTD,并且已经发布到互联网中。

公共DTD语法:

代码示例:

XML:可扩展标记语言_第4张图片

3. 总结

DTD是较简单的语法检查机制。整体语法较简单,功能较单一。

当需要对XML文件结构更新时,需要修改整个DTD文件,不够灵活。

四、XSD

1. 简介

XSD(XML Schema Definition )XML模式定义。

属于DTD的升级版。完美的解决了DTD使用时不易扩展问题,并且提供了更强大功能。

2. 定义XSD

新建xxx.xsd。

所有需要的元素、属性都需要被定义。


<aa:schema xmlns:aa="http://www.w3.org/2001/XMLSchema">
  
  <aa:element name="students">
    
    <aa:complexType>
      
      <aa:sequence>
        
        
        <aa:element ref="student" maxOccurs="2"/>
      aa:sequence>
    aa:complexType>
  aa:element>
  <aa:element name="student">
    
    <aa:complexType>
      <aa:sequence>
        
        <aa:element name="name" type="aa:string"/>
        <aa:element name="age" type="aa:int"/>
        <aa:element name="sex" type="aa:boolean"/>
      aa:sequence>
      
      <aa:attribute name="id" use="optional" fixed="aa"/>
    aa:complexType>
  aa:element>
aa:schema>

3. 引用xsd


<students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="s.xsd">
  <student id="aa">
    <name>name>
    <age>11age>
    <sex>falsesex>
  student>
students>

五、XML 解析

1. 简介

在Java中提供了两种XML解析方式:DOM、SAX。

2. DOM解析

Document Object Model 文档对象模型。把XML文件一次性加载到内存中,并转换为树状模型。然后一个节点一个节点的解析,这种解析方式效率较高,但是比较消耗内存,适用于小型XML文档。

XML:可扩展标记语言_第5张图片

3. SAX

SAX(Simple API for XML)解析:是基于事件的解析,它是为了解决DOM解析的资源耗费而出现的。SAX在解析一份XML文档时,会依次出发文档开始、元素开始、元素结束、文档结束等事件,应用程序通过监听解析过程中所触发的事件即可获取XML文档的内容。该方式不需要事先调入整个文档,优势是占用资源少,内存消耗小,一般在解析数据量较大的文档是采用该方式。

六、DOM解析

1. 简介

DOM解析所有API都是org.w3c包中。

使用DOM操作XML按照标准树状结构一层一层解析。

解析器是基于工厂设计模式的。当获取到文档对象后每个元素都是一个节点,然后操作节点对象。

在DOM解析时,每个换行符都是一个文本节点,所以一定要过滤掉换行。

XML:可扩展标记语言_第6张图片

2. 代码示例

以上面的students作为xml进行解析。

已知XML文件就三层结构,所以直接使用循环进行解析。如果XML文档结构比较深,此处需要使用递归。

public class TestDOM {
  public static void main(String[] args) throws Exception {
    parse();
  }
  //使用DOM解析XML
  public static void parse() throws ParserConfigurationException, IOException, SAXException {
    //1.获取document构建 工厂对象
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    //2.根据文档构建工厂获取文档构建对象
    /*
     * 将xml变为document
     * 手动的创建document
     * */
    DocumentBuilder db = dbf.newDocumentBuilder();
    //3.使用文档构建对象, 将xml解析为document对象
    Document document = db.parse(new File("stu.xml"));
    //4.根据标签名获取根标签
    NodeList rootList = document.getElementsByTagName("students");
    //5.xml中仅会存在一个根标签, 获取这个根标签
    Node root = rootList.item(0);
    System.out.println("根节点名称: " + root.getNodeName());
    //6.获取标签所有的直接子节点
    NodeList childNodes = root.getChildNodes();
    for (int i = 0; i < childNodes.getLength(); i++) {
      //7.获取每一个子节点
      /*
       * getNodeType(): 结点类型, 常量
       *           1: 标签结点
       *           2: 属性结点
       *           3: 文本结点
       * */
      Node item = childNodes.item(i);
      if (item.getNodeType() == Node.ELEMENT_NODE) {
        System.out.println(" 子节点名称: " + item.getNodeName());
        //8.获取该结点的所有子节点
        NodeList childNodes1 = item.getChildNodes();
        for (int j = 0; j < childNodes1.getLength(); j++) {
          Node item1 = childNodes1.item(j);
          if (item1.getNodeType() == Node.ELEMENT_NODE) {
            System.out.println("   子节点名称: " + item1.getNodeName() + " : " + item1.getTextContent());
          }
        }
      }
    }
  }
}

七、使用DOM生成XML

1. 简介

DOM生成XML时主要是创建节点。然后把节点添加到上层节点。

2. 代码示例

public class TestDOM {
  public static void main(String[] args) throws Exception {
    transform();
  }
  //先构建文档, 再将文档变为xml
  public static void transform() throws ParserConfigurationException, TransformerException, FileNotFoundException {
    //1.获取文档构建器工厂对象
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    //2.构建器工厂对象 获取 构建器对象
    DocumentBuilder db = dbf.newDocumentBuilder();
    //3.创建文档对象
    Document document = db.newDocument();
    //4.创建teachers标签
    Element teachers = document.createElement("teachers");
    //5.创建teacher标签
    Element teacher = document.createElement("teacher");
    teacher.setAttribute("id", "tea"); //设置属性
    //6.创建name标签
    Element name = document.createElement("name");
    name.setAttribute("class", "na"); //设置属性
    name.setTextContent("zs");
    //7.创建age标签
    Element age = document.createElement("age");
    age.setTextContent("18");
    //8.创建sex标签
    Element sex = document.createElement("sex");
    sex.setTextContent("男");

    //9.设置标签之间的关系
    /* 添加teacher的子标签 */
    teacher.appendChild(name);
    teacher.appendChild(age);
    teacher.appendChild(sex);
    /* 添加teachers的子标签 */
    teachers.appendChild(teacher);
    /* 添加文档的子标签 */
    document.appendChild(teachers);
    /* 设置为独立的xml */
    document.setXmlStandalone(true);

    //10.将document对象变为xml
    //10.1 创建转换器工厂对象
    TransformerFactory tff = TransformerFactory.newInstance();
    //10.1 根据转换器工厂对象 获取 转换器
    Transformer tf = tff.newTransformer();
    tf.setOutputProperty(OutputKeys.INDENT, "yes");
    tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
    //10.3 将document转化为xml  通过流输出到指定的位置
    /*
     * 参数1: 指定document源
     * 参数2: 输出的位置
     * */
    tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("teacher.xml")));
  }
}

八、SAX解析

1. 简介

SAX解析是基于事件模型完成的。所有的API都在org.xml中。

SAX解析时也会识别换行为文本节点,这个坑一定躲避。

2. 代码示例

public class TestSAX {
  public static void main(String[] args) throws Exception {
    parse();
  }
  public static void parse() throws Exception {
    //1.SAX解析器工厂对象
    SAXParserFactory spf = SAXParserFactory.newInstance();
    //2.基于工厂对象获取解析器对象
    SAXParser sp = spf.newSAXParser();
    //3.使用解析器解析xml
    sp.parse(new File("java_day13/teacher.xml"), new MyHandler());
  }

  public class MyHandler extends DefaultHandler {
    String name = null;

    @Override
    public void startDocument() throws SAXException {
      System.out.println("文档开始解析");
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      System.out.println("开始解析, 标签名: " + qName);
      name = qName;
    }

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

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
      System.out.println("解析结束, 标签名: " + qName);
    }

    @Override
    public void endDocument() throws SAXException {
      System.out.println("文档解析结束");
    }
  }

}

九、SAX 生成

1. 简介

SAX 生成XML 和手写XML比较相似。

也是在调用5个操作方法。

2. 代码示例

public class TestSAX {
  public static void main(String[] args) throws Exception {
    parse();
  }
  public void transfom() throws TransformerConfigurationException, FileNotFoundException, SAXException {
    //1.创建转换器工厂
    SAXTransformerFactory stff = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
    //2.根据工厂获取转换器
    /*
     * 传输
     * 创建xml
     * */
    TransformerHandler th = stff.newTransformerHandler();
    
    Transformer transformer = th.getTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
    
    th.setResult(new StreamResult(new FileOutputStream("stu.xml")));
    th.startElement(null, null, "students", null);
    AttributesImpl attributes = new AttributesImpl();
    attributes.addAttribute(null, null, "id", null, "aa");
    th.startElement(null, null, "student", attributes);
    th.startElement(null, null, "name", null);
    char[] chars = "zs".toCharArray();
    th.characters(chars, 0, chars.length);
    th.endElement(null, null, "name");
    th.startElement(null, null, "age", null);
    char[] chars1 = "19".toCharArray();
    th.characters(chars1, 0, chars1.length);
    th.endElement(null, null, "age");
    th.startElement(null, null, "sex", null);
    char[] chars2 = "男".toCharArray();
    th.characters(chars2, 0, chars2.length);
    th.endElement(null, null, "sex");
    th.endElement(null, null, "student");
    th.endElement(null, null, "students");
    th.endDocument();
  }
}

作业:

使用SAX | DOM 解析xml, 将解析xml的代码封装到一个方法中, 调用该方法返回一个对象(将xml解析的内容创建对象. 设置属性值, 返回对象)

<phone id="iph">
  <name>lsname>
  <price>1999price>
  <color>黑色color>
phone>

解析后:
	phone对象 属性值 name ls  price 1999 color 黑色

你可能感兴趣的:(java,xml,前端,服务器,java-ee,后端,java)