导学

在经过之前Java部分的学习后,今天我们开始学习Java Web部分的知识。那么在学习之前,我们需要了解XML的相关知识。XML是一种以.xml为后缀的文件,这种文件通常用于保存数据,也常常用来作为项目的配置文件。
XML的全称为EXtensible Markup Language,可扩展标记语言。编写XML就是编写标签,形式与HTML非常类似。

  1. XML和之前讲解过的Json作用其实相同的,都是为了保存数据。
  2. XML没有预制标签都是自己定义的。
  3. XML本身标签存在一定含义,并且语法格式非常规范,存在良好的人机可读性

比如:

  1. person.xml
  2. <person>
  3. <name>张三</name>
  4. <age>23</age>
  5. <sex></sex>
  6. <height>178</height>
  7. <height>75</weight>
  8. </person>
  9. school.xml
  10. <school>
  11. <class no="J121">
  12. <name>Java全日制121班</name>
  13. <count>5</count>
  14. </class>
  15. <class no="JY3">
  16. <name>Java业余3班</name>
  17. <count>4</count>
  18. </class>
  19. </school>

无论是对于开发人员,还是计算机来说。这种规则的文档都是非常有利于理解和解析的。
XML与HTML的比较

  1. XML与HTML非常相似,都是编写标签
  2. XML没有预定义标签,HTML存在大量预定义标签
  3. XML重在保存与传输数据,HTML用于显示信息

XML的用途

  1. Java程序的配置描述文件
    比如:web应用配置文件,某些程序的适配项,如果写死在程序中,进行修改的时候需要重新编译,这时候就可以考虑将内容写入XML配置文件

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    5. id="WebApp_ID" version="3.1">
    6. <display-name>demo3</display-name>
    7. <welcome-file-list>
    8. <welcome-file>Login2Servlet</welcome-file>
    9. </welcome-file-list>
    10. <filter>
    11. <filter-name>EncodingFilter</filter-name>
    12. <filter-class>cn.filters.EncodingFilter</filter-class>
    13. <init-param>
    14. <param-name>Encoding</param-name>
    15. <param-value>UTF-8</param-value>
    16. </init-param>
    17. </filter>
    18. </web-app>
  2. 用于保存程序产生的数据
    相较于普通文件,XML文件中的格式是规范的,是有序的。可以使使用者更轻易的放置和读取数据。

  3. 网络间的数据传输
    在进行网络信息传输的时候,发送方可以将内容组织成XML,接收方接收到内容后,可以按照相互之间约定的格式进行解析。

    XML的语法规则

    XML文档结构

  4. 第一行必须是XML声明
    XML声明说明XML文档的基本信息,包括版本号与字符集,写在XML第一行

    1. <?xml version="1.0" encoding="UTF-8"?>
  5. 有且只有一个根节点

  6. XML标签的书写规则与HTML相同

    XML标签书写规则

  • 适当的注释<!-- -->与缩进
  • 合理的标签名
    1. 标签名要有意义
    2. 建议使用英文,小写字母,单词之间使用-进行分割
    3. 建议多级标签之间不要存在重名的情况
  • 合理使用属性
    1. 标签属性用于描述标签不可或缺的信息
    2. 对标签分组或者为标签设置id时常用属性表示
  • 特殊字符与CDATA标签标签体中,出现<``>特殊字符,会破坏文档结构如:

    1. <example>
    2. <question>3+4>6</question>
    3. </example>
  • 可以使用实体引用CDATA标签解决该问题

    1. 实体引用: | 实体引用 | 对应符号 | | :—- | :—- | | &lt; | < | | &gt; | > | | &amp; | & | | &apos; | ' | | &quot; | " |

    2. CDATA标签
      CDATA标签指的是不应由XML解析器进行解析的文本内容,使用<![CDATA[开始 ~ 结束]]>将该部分内容包裹起来,原意输出

  • 有序的子元素
    指的是在多层嵌套的子元素中,标签的前后顺序应保持一致

    XML语义约束

    在XML中文档结构正确,但可能不是有效的。
    比如在关于员工档案的XML文档中,不允许出现有关植物品种的标签,XML语义约束指的就是规定XML文档中允许出现哪些元素
    XML的语义约束有两种定义方式:DTD和XML Schema;
    DTD
    DTD(Document Type Definition 文档类型定义),是一种简单易用的语义约束方式。
    DTD文件的扩展名为.dtd
    <!ELEMENT>定义XML文档允许出现的节点和数量。 ```xml <!ELEMENT>定义XML文档允许出现的节点和数量。

例如:定义hr节点下只允许出现一个employee子节点。 <!ELEMENT hr(employee)> 定义hr节点下至少出现一个employee子节点。 <!ELEMENT hr(employee+)> 定义hr节点下可以出现0…n个employee子节点。 <!ELEMENT hr(employee*)> 定义hr节点下可以最多出现一个employee子节点。 <!ELEMENT hr(employee?)>

定义hr节点标签体只能是文本。 <!ELEMENT hr(#PCDATA)>

定义hr节点只能有四个子节点,并且按顺序排列。 <!ELEMENT hr(name,age,salary,department)>

<!ATTLIST>定义XML文档中元素的属性。

例如:定义employee节点属性no的默认值为”” <!ATTLIST employee no CDATA “”>

  1. XML中使用标签引用DTD文件<br />`<!DOCTYPE 根节点 SYSTEM "dtd文件路径">`<br />示例<br /><!DOCTYPE hr SYSTEM "hr.dtd">
  2. **XML Schema**
  3. > Schemadtd更复杂 高级的约束性语言
  4. > 提供了数据类型 格式限定 数据范围等特性
  5. > Schema w3c标准的标准规范
  6. ```xml
  7. <?xml version="1.0" encoding="UTF-8"?>
  8. <!-- 人力资源管理信息 -->
  9. <!-- xmlns:xsi属性的值用来告诉xml文档,使用的是schema约束 -->
  10. <employee-data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  11. xsi:noNamespaceSchemaLocation="hr.xsd">
  12. <employee nid="3309">
  13. <name>张三</name>
  14. <age>24</age>
  15. <salary>5000</salary>
  16. <department>
  17. <dname>会计部</dname>
  18. <address>数字大厦</address>
  19. </department>
  20. </employee>
  21. <employee nid="3310">
  22. <name>李四</name>
  23. <age>25</age>
  24. <salary>5600</salary>
  25. <department>
  26. <dname>开发部</dname>
  27. <address>数字大厦</address>
  28. </department>
  29. </employee>
  30. </employee-data>
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <schema xmlns="http://www.w3.org/2001/XMLSchema">
  3. <element name="employee-data"><!-- 表明根节点是employee-data -->
  4. <!-- complexType标签含义是复杂节点,包含子节点的时候必须使用这个标签 -->
  5. <!-- 因为employee是根节点,下面有很多的子节点,所以必须使用 -->
  6. <complexType>
  7. <sequence><!-- 序列:表明其下的子节点必须按照顺序前后严格书写 -->
  8. <!-- minOccurs="1" maxOccurs="999"表示该节点最少出现一次,最大出现999次 -->
  9. <element name="employee" minOccurs="1" maxOccurs="999">
  10. <complexType>
  11. <sequence>
  12. <!-- type="string"表明该节点中只能输入字符串,不能拥有子节点 -->
  13. <element name="name" type="string"></element>
  14. <!-- type="integer"表明该节点中只能输入数字,不能拥有子节点 -->
  15. <element name="age">
  16. <simpleType>
  17. <restriction base="integer"><!-- 表示数值范围 -->
  18. <minInclusive value="18"></minInclusive>
  19. <maxInclusive value="60"></maxInclusive>
  20. </restriction>
  21. </simpleType>
  22. </element>
  23. <element name="salary" type="integer"></element>
  24. <element name="department">
  25. <complexType>
  26. <sequence>
  27. <element name="dname" type="string"></element>
  28. <element name="address" type="string"></element>
  29. </sequence>
  30. </complexType>
  31. </element>
  32. </sequence>
  33. <!-- use="required"表示nid属性在任何employee节点上必须存在 -->
  34. <attribute name="nid" type="string" use="required"></attribute>
  35. </complexType>
  36. </element>
  37. </sequence>
  38. </complexType>
  39. </element>
  40. </schema>

Java解析XML

Java可以使用DOM、SAX、DOM4j、JDOM等方式解析XML文档,最常用的还是属于DOM4j
DOM4jjar包下载地址:https://dom4j.github.io
image.png

xml:解析

  1. package com.dodoke.dom4j;
  2. import java.util.List;
  3. import org.dom4j.Attribute;
  4. import org.dom4j.Document;
  5. import org.dom4j.DocumentException;
  6. import org.dom4j.Element;
  7. import org.dom4j.io.SAXReader;
  8. public class HrReader {
  9. public void readXml(){
  10. String file= "d:/workspace/myxml/src/hr.xml";
  11. //SAXReader类是读取XML文件的核心类,用于将XML解析后以“树”的形式保存在内容中
  12. SAXReader reader = new SAXReader();
  13. try {
  14. Document document = reader.read(file);
  15. //获取XML文档的根节点。即hr标签。
  16. Element root = document.getRootElement();
  17. //element方法 用于获取指定的标签集合
  18. List<Element> employees = root.elements("employee");
  19. for(Element employee:employees){
  20. //element方法用于获取唯一的子节点对象
  21. Element name = employee.element("name");
  22. String empName = name.getText();//getText()方法用于获取标签文本
  23. System.out.println(empName);
  24. System.out.println(employee.elementText("age"));
  25. System.out.println(employee.elementText("salary"));
  26. Element department = employee.element("department");
  27. System.out.println(department.element("dname").getText());
  28. System.out.println(department.element("address").getText());
  29. //获取属性信息
  30. Attribute att = employee.attribute("no");
  31. System.out.println(att.getText());
  32. }
  33. } catch (DocumentException e) {
  34. // TODO Auto-generated catch block
  35. e.printStackTrace();
  36. }
  37. }
  38. public static void main(String[] args) {
  39. HrReader reader = new HrReader();
  40. reader.readXml();
  41. }
  42. }
  1. import java.io.File;
  2. import java.util.Iterator;
  3. import java.util.List;
  4. import org.dom4j.Attribute;
  5. import org.dom4j.Document;
  6. import org.dom4j.Element;
  7. import org.dom4j.io.SAXReader;
  8. public class DOM4jDemo {
  9. public static void main(String[] args) throws Exception {
  10. //1.创建Reader对象
  11. //SAXReader类是读取XML文件的核心类,用于将XML解析后以“树”的形式保存在内容中
  12. SAXReader reader = new SAXReader();
  13. //2.加载xml,获取整个文档的document对象
  14. Document document = reader.read(new File("src/com/ntdodoke/JDBCStudy/hr.xml"));
  15. //3.获取根节点
  16. Element rootElement = document.getRootElement();
  17. //或者采用rootElement.elementText("name")方法输出节点文本值
  18. //创建迭代器准备迭代
  19. Iterator<Element> iterator = rootElement.elementIterator();
  20. while (iterator.hasNext()){
  21. Element stu = iterator.next();
  22. //获取节点的属性
  23. List<Attribute> attributes = stu.attributes();
  24. System.out.println("======获取属性值======");
  25. for (Attribute attribute : attributes) {
  26. System.out.println(attribute.getValue());
  27. }
  28. System.out.println("======遍历子节点======");
  29. Iterator<Element> iteratorSon = stu.elementIterator();
  30. while (iteratorSon.hasNext()){
  31. Element stuChild = iteratorSon.next();
  32. System.out.println("节点名:"+stuChild.getName()+"---节点值:"+stuChild.getStringValue());
  33. }
  34. }
  35. }
  36. }

xml:更新

  1. import java.io.FileOutputStream;
  2. import java.io.OutputStreamWriter;
  3. import java.io.Writer;
  4. import org.dom4j.Document;
  5. import org.dom4j.Element;
  6. import org.dom4j.io.SAXReader;
  7. public class Demo4jWriter {
  8. public static void main(String[] args) {
  9. writeXml();
  10. }
  11. public static void writeXml(){
  12. String file = "src/com/ntdodoke/JDBCStudy/hr.xml";
  13. SAXReader reader = new SAXReader();
  14. try {
  15. Document document = reader.read(file);
  16. Element root = document.getRootElement();
  17. Element employee = root.addElement("employee");
  18. employee.addAttribute("nid", "3311");
  19. Element name = employee.addElement("name");
  20. name.setText("李铁柱");
  21. employee.addElement("age").setText("37");
  22. employee.addElement("salary").setText("3600");
  23. Element department = employee.addElement("department");
  24. department.addElement("dname").setText("人事部");
  25. department.addElement("address").setText("数字大厦-B105");
  26. Writer writer = new OutputStreamWriter(new FileOutputStream(file) , "UTF-8");
  27. document.write(writer);
  28. writer.close();
  29. } catch (Exception e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. }

XPath路径表达式

XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。
XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力。
XPath路径是XML文档中查找数据的语言,掌握XPath可以极大的提高在提取数据时的开发效率。
学习XPath本质就是掌握各种表达式的使用技巧。
XPath基本表达式
1.XML - 图2
XPath基本表达式使用案例
1.XML - 图3
XPath谓语表达式
1.XML - 图4
Jaxen介绍:
Jaxen是一个Java编写的开源的XPath库,能适应不同的不同的对象模型,包括DOM、XOM、DOM4j和JDOM,DOM4j底层依赖Jaxen实现XPath查询。
Jaxen下载地址:https://maven.aliyun.com/mvn/view
可以到阿里云的镜像仓库下载想要的jar包