[关闭]
@MRsunhuimin 2020-09-07T14:45:44.000000Z 字数 7421 阅读 210

XML&DOM4J (07.31)

java基础

作者:孙慧敏

1. XML标签

1.0 什么是XML

    1. XML指可扩展标记语言(EXtensible Markup Language)。

    2. XML是一种标记语言,很类似HTML(超文本标记语言)。

    3. XML的设计宗旨是传输数据,而非显示数据。

    4. XML标签没有被预定义。您需要自行定义标签。

    5. XML被设计为具有自我描述性。

    6. XML是 W3C 的推荐标准。

1.1 格式

XML文档内容由一系列标签元素组成

格式:<元素名 属性名=“属性值”>元素内容</元素名>

属性值用双引号包裹
一个元素可以有多个属性
属性值中不能直接包含<、“、&
不建议使用的字符:‘、>
空元素:
    <name>  </name>
    <name></name>
    <name/>

1.2 XML语法规范

1. 声明一个xml文件
    <?xml version="1.0" encoding="utf-8"?>

2. 文档节点部分
    <节点名></节点名>
    节点/元素/标签一个意思
    标签属性,区分大小写,默认全小写
    或者作为单标签,自闭和<br />

3. 整个文档只能有一个根节点
    如<root><a></a></root>对
    <root></root><a></a>错

4. 标签可以嵌套,但不可以互嵌套
    <root><a></root></a>

5. 属性写法
    属性必有值,推荐小写,必须双引号括住
    html中
    <input type="text" disabled>
    <select>
    <option>大</option>
    <option selected>小</option>
    <option>中</option>
    </select>
    ----<option selected="selected">小</option>--
6. 注释的写法
    <!---这是注释---->

7.特殊字符要用实体来表示(转义)
    '->&apos;
    "->&quot
    >->&gt;
    &->&lt;

7. 如果文章中有大量'"<>
    定界符CDATA来放大段文本时不考虑
    <![CDATA[内容]]>

8. 一切皆节点,包括,空格,换行,注释

1.3 XML编写注意事项

1. 所有XML元素都必须有结束标签

2. XML标签对大小写敏感

3. XML必须正确的嵌套

4. 同级标签以缩进对齐

5. 元素名称可以包含字母、数字或其他的字符

6. 元素名称不能以数字或者标点符号开始

7. 元素名称中不能含空格

1.4 XML和HTML的主要区别

  1. XML是用来存放数据的

  2. XML不是HTML的替代品,XML和HTML是两种不同用途的语言。

  3. XML是被设计用来描述数据的,重点是:什么是数据,如何存放数据。

  4. HTML是被设计用来显示数据的,重点是:显示数据以及如何显示数据更好上面。

2. XML解析器

2.1 解析器类型

    1. 非验证解析器
    作用:检查文档格式是否良好

    2. 验证解析器
    作用:使用DTD检查文档的有效性

3. XML命名空间

3.1 XML命名空间的作用

    用于解决在复杂、大型XML文件中,出现名称相同,但是含义不同的元素

4. 解析XML技术

4.1 DOM

4.1.1 解释
    文档对象模型(Document Object Model)
    DOM把XML文档映射成一个倒挂的树

    DOM解析包:org.w3c.dom
4.1.2 保存XML文件步骤:
        获得TransformerFactory对象
        创建Transformer对象
        创建DOMSource对象
        包含XML信息
        设置输出属性
        编码格式
        创建StreamResult对象
        包含保存文件的信息
        将XML保存到指定文件中
4.1.3 修改/删除DOM节点
    1. 给所有的Brand标签添加id属性
            获取Brand标签
            调用setAttribute()方法添加属性

    2. 删除Brand值为“华为”的标签
            getElementsByTagName()方法获取Brand标签列表
            获得Brand值为“华为”的标签对象
            通过getParentNode()方法获得父节点对象
            调用父节点的removeChild()方法删除节点
4.1. 特点:
    1. 基于XML文档树结构的解析

    2. 适用于多次访问的XML文档

    3. 特点:比较消耗资源

4.2 SAX

特点:
    1. 基于事件的解析

    2. 适用于大数据量的XML文档

    3. 特点:占用资源少,内存消耗小

4.3 DOM4J

4.3.1概念:
    1. dom4j是一个Java的XML API,是dom4j.org 出品的一个开源 XML 解析包,是jdon升级版,用来读写XML文件

    2. DOM4j是一个易用,开源的库,用于XML,Xpath,XSLT,它应用于Java平台,采用Java集合框架并完全支持DOM,SAX和JAXP

    3. DOM4j整合两种思想(SAX、DOM)
        使用SAX的思想读取XML

        使用DOM的思想,在内存中创建一颗对象关系树,可以参照之前学的DOM


    4. 解析XML文档,读写XML文档主要依赖于org.dom4j.io包,其中提供两个类: 
        1.DOMReader

        2.SAXReader
        (这两个类的调用方式是一致的)
4.3.2特点:
    1. 非常优秀的Java XML API

    2. 性能优异、功能强大

    3. 开放源代码

5. 举例

5.1 获取当前xml文档节点的内容

  1. package com.java_high.dom4j;
  2. /*
  3. * 节点/元素/标签一个意思
  4. */
  5. import java.util.List;
  6. import org.dom4j.Document;
  7. import org.dom4j.DocumentException;
  8. import org.dom4j.Element;
  9. import org.dom4j.io.SAXReader;
  10. public class test01 {
  11. public static void main(String[] args) {
  12. //将xml文件加载到内存中 XML解析器
  13. SAXReader saxReader = new SAXReader();
  14. try {
  15. //document 加载执行xml文档获取Document对象
  16. Document document = saxReader.read("src/com/java_high/dom4j/stu.xml");
  17. //获取XML根节点getRootElement()
  18. Element rootelement = document.getRootElement();
  19. //获取当前节点下所有子节点 elements()——><user>
  20. List<Element> elements = rootelement.elements();
  21. //第一个增强for循环获取根节点下子所有节点的子节点
  22. for (Element ele : elements) {
  23. //list集合存储6个属性
  24. List<Element> ele2 = ele.elements();
  25. //增强for循环遍历
  26. for (Element ele3 : ele2) {
  27. //获取当前节点属性 attributeValue(“属性名”)
  28. System.out.println(ele3.attributeValue("val"));
  29. }
  30. }
  31. } catch (DocumentException e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <student>
  3. <user>
  4. <!-- 姓名 -->
  5. <name val="张三"/>
  6. <!-- 预计成绩 -->
  7. <score val="80"/>
  8. <!-- 最终成绩 -->
  9. <score1 val="90"/>
  10. </user>
  11. <user>
  12. <name val="李四"/>
  13. <score val="70"/>
  14. <score1 val="95"/>
  15. </user>
  16. </student>

5.2 为xml文档删除/改变指定的属性值

  1. package com.java_high.dom4j;
  2. import java.io.FileWriter;
  3. import java.util.List;
  4. import org.dom4j.Document;
  5. import org.dom4j.DocumentException;
  6. import org.dom4j.Element;
  7. import org.dom4j.io.OutputFormat;
  8. import org.dom4j.io.SAXReader;
  9. import org.dom4j.io.XMLWriter;
  10. public class test02 {
  11. public static void main(String[] args) throws Exception {
  12. SAXReader saxReader = new SAXReader();
  13. try {
  14. Document doc = saxReader.read("src/com/java_high/dom4j/change.xml");
  15. Element rootElement = doc.getRootElement();
  16. List<Element> elements = rootElement.elements();
  17. for (Element ele1 : elements) {
  18. String elename = ele1.attributeValue("name");
  19. if (elename.equals("苹果")) {
  20. //删除
  21. //rootElement.remove(ele1);
  22. ele1.addAttribute("name", "小米");
  23. }
  24. }
  25. OutputFormat frm = OutputFormat.createPrettyPrint();
  26. frm.setEncoding("GBK");
  27. FileWriter fw = new FileWriter("src/com/java_high/dom4j/change.xml");
  28. XMLWriter xmlWriter = new XMLWriter(fw,frm);
  29. xmlWriter.write(doc);
  30. xmlWriter.close();
  31. System.out.println("替换成功!");
  32. } catch (DocumentException e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. }
  1. <?xml version="1.0" encoding="GBK"?>
  2. <PhoneInfo>
  3. <Brand name="华为">
  4. <Type name="U8650"/>
  5. <Type name="HW123"/>
  6. <Type name="HW321"/>
  7. </Brand>
  8. <Brand name="小米">
  9. <Type name="iPhone4"/>
  10. </Brand>
  11. </PhoneInfo>

5.3 xml添加指定节点和属性

  1. package com.java_high.dom4j;
  2. import java.io.FileWriter;
  3. import org.dom4j.Document;
  4. import org.dom4j.DocumentException;
  5. import org.dom4j.Element;
  6. import org.dom4j.io.OutputFormat;
  7. import org.dom4j.io.SAXReader;
  8. import org.dom4j.io.XMLWriter;
  9. /*
  10. * 添加新的Brand:三星
  11. * 给Brand节点添加新的子标签Type:Note4
  12. */
  13. public class test03 {
  14. public static void main(String[] args) throws Exception {
  15. //将xml文件加载到内存中 XML解析器
  16. SAXReader saxReader = new SAXReader();
  17. try {
  18. //doc加载执行xml文档获取Document对象
  19. Document doc = saxReader.read("src/com/java_high/dom4j/add.xml");
  20. //获取XML根节点getRootElement()
  21. Element rootElement = doc.getRootElement();
  22. //在根节点下创建新节点Brand,并创建节点名和属性
  23. Element element1 = rootElement.addElement("Brand");
  24. element1.addAttribute("name", "三星");
  25. //同理,在新的节点Brand下创建子节点,并创建节点名和属性
  26. Element element2 = element1.addElement("Type");
  27. element2.addAttribute("name", "Note4");
  28. //添加文本内容
  29. element2.setText("2800");
  30. //通过OutputFormat的静态方法createPrettyPrint()创建OutputFormat对象,并设置编码集
  31. OutputFormat frm = OutputFormat.createPrettyPrint();
  32. frm.setEncoding("GBK");
  33. //写入XML文件的位置,以及指定的格式
  34. FileWriter fw = new FileWriter("src/com/java_high/dom4j/add.xml");
  35. XMLWriter xmlWriter = new XMLWriter(fw,frm);
  36. //开始写入XML文件 写入Document对象
  37. xmlWriter.write(doc);
  38. xmlWriter.close();
  39. System.out.println("添加完成!");
  40. } catch (DocumentException e) {
  41. e.printStackTrace();
  42. }
  43. }
  44. }
  1. <?xml version="1.0" encoding="GBK"?>
  2. <PhoneInfo>
  3. <Brand name="华为">
  4. <Type name="U8650"/>
  5. <Type name="HW123"/>
  6. <Type name="HW321"/>
  7. </Brand>
  8. <Brand name="苹果">
  9. <Type name="iPhone4"/>
  10. </Brand>
  11. <Brand name="三星">
  12. <Type name="Note4">2800</Type>
  13. </Brand>
  14. </PhoneInfo>

5.4 在xml中添加节点

  1. package com.java_high.dom4j;
  2. import java.io.FileWriter;
  3. import org.dom4j.Document;
  4. import org.dom4j.DocumentHelper;
  5. import org.dom4j.Element;
  6. import org.dom4j.io.OutputFormat;
  7. import org.dom4j.io.XMLWriter;
  8. /*
  9. * 创建根节点和其子节点,并赋予他们属性
  10. * 前提:需要手动创建xml文件
  11. */
  12. public class test04 {
  13. public static void main(String[] args) throws Exception {
  14. Document doc = DocumentHelper.createDocument();
  15. Element rootElement = doc.addElement("PhoneInfo");
  16. Element ele1 = rootElement.addElement("Brand");
  17. ele1.addAttribute("name", "红米");
  18. Element ele2 = ele1.addElement("Type");
  19. ele2.setText("Note 7 Pro");
  20. OutputFormat frm = OutputFormat.createPrettyPrint();
  21. frm.setEncoding("GBK");
  22. FileWriter fw = new FileWriter("src/com/java_high/dom4j/new.xml");
  23. XMLWriter xmlWriter = new XMLWriter(fw,frm);
  24. xmlWriter.write(doc);
  25. xmlWriter.close();
  26. System.out.println("创建新的xml成功!");
  27. }
  28. }
  1. <?xml version="1.0" encoding="GBK"?>
  2. <PhoneInfo>
  3. <Brand name="红米">
  4. <Type>Note 7 Pro</Type>
  5. </Brand>
  6. </PhoneInfo>

6. 和转义字符

https://www.cnblogs.com/catgatp/p/6403382.html

    被<![CDATA[]]>这个标记所包含的内容将表示为纯文本,比如<![CDATA[<]]>表示文本内容“<”。

    此标记用于xml文档中,我们先来看看使用转义符的情况。我们知道,在xml中,”<”、”>”、”&”等字符是不能直接存入的,否则xml语法检查时会报错,如果想在xml中使用这些符号,必须将其转义为实体,如”&lt;”、”&gt;”、”&amp;”,这样才能保存进xml文档。

    在使用程序读取的时候,解析器会自动将这些实体转换回”<”、”>”、”&”。举个例子:
  <age> age < 30 </age>
  
  上面这种写法会报错,应该这样写:
  <age> age &lt; 30 </age>
  
  值得注意的是:
  (1)转义序列字符之间不能有空格;
  (2) 转义序列必须以”;”结束;
  (3) 单独出现的”&”不会被认为是转义的开始;
  (4) 区分大小写。
  1. 在XML中,需要转义的字符有:
  2.   (1)&   &amp;
  3.   (2)<   &lt;
  4.   (3)>   &gt;
  5.   (4)"   &quot;
  6.   (5)'   &apos;
    但是严格来说,在XML中只有”<”和”&”是非法的,其它三个都是可以合法存在的,但是,把它们都进行转义是一个好的习惯。

    不管怎么样,转义前的字符也好,转义后的字符也好,都会被xml解析器解析,为了方便起见,使用<![CDATA[]]>来包含不被xml解析器解析的内容。
  1. 但要注意的是:
  2.   (1) 此部分不能再包含”]]>”;
  3.   (2) 不允许嵌套使用;
  4.   (3)”]]>”这部分不能包含空格或者换行。
  5.   
  6.   最后,说说<![CDATA[]]>和xml转移字符的关系,它们两个看起来是不是感觉功能重复了?
  7.   是的,它们的功能就是一样的,只是应用场景和需求有些不同:
  8.   (1)<![CDATA[]]>不能适用所有情况,转义字符可以;
  9.   (2) 对于短字符串<![CDATA[]]>写起来啰嗦,对于长字符串转义字符写起来可读性差;
  10.   (3) <![CDATA[]]>表示xml解析器忽略解析,所以更快。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注