XML 教程

什么是 XML?

XML(Extensible Markup Language,可扩展标记语言)是一种用于存储和传输数据的标记语言。它不预定义任何标签,允许开发者自定义标签来描述数据,是 W3C 的标准格式。

XML 的核心特点

  • 纯文本:与平台无关,任何系统都能读取
  • 自描述:标签本身说明数据含义
  • 可扩展:自定义标签,没有固定词汇表
  • 结构化:树形层级,表达复杂关系
  • 标准统一:W3C 制定,工具生态成熟

简单示例

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="编程">
    <title>XML 入门教程</title>
    <author>张三</author>
    <price>59.00</price>
  </book>
</bookstore>

XML 的用途

  • 配置文件(web.xml、pom.xml、Spring 配置)
  • 数据交换(Web Service SOAP、RSS)
  • 文档格式(Office Open XML、SVG)
  • 数据传输(Android/iOS 网络数据)
  • 数据库(原生 XML 数据库)

XML vs HTML

特性XMLHTML
用途存储/传输数据显示数据
标签自定义预定义
大小写区分不区分
结束标签必须有可省略
空格保留折叠

XML 简介

XML 简介

XML 由 W3C 于 1998 年发布 1.0 标准,用于以结构化的纯文本方式描述数据。

XML 能做什么

  • 数据存储:以树形结构保存数据
  • 数据交换:系统间交换数据的通用格式(如 Web Services)
  • 配置管理:程序配置文件(Java 的 web.xml、Maven 的 pom.xml)
  • 文档描述:XHTML、SVG 等都是 XML 的应用

XML 文档结构

<?xml version="1.0" encoding="UTF-8"?>   <!-- 声明 --%>
<root>                                     <!-- 根元素 --%>
  <child attribute="value">内容</child>   <!-- 子元素+属性 --%>
</root>

一个完整的 XML

<?xml version="1.0" encoding="UTF-8"?>
<student>
  <name>小明</name>
  <age>18</age>
  <courses>
    <course>数学</course>
    <course>语文</course>
  </courses>
</student>

XML 的优点

1. 简单易学:纯文本,规则少
2. 通用性强:跨平台、跨语言
3. 可读性好:结构一目了然
4. 标准成熟:解析工具丰富(Java DOM/SAX、Python ElementTree 等)

XML 的缺点

1. 冗余大:标签重复,文件体积大
2. 解析慢:相比二进制格式
3. 语法严格:标签必须正确闭合
现代替代:JSON(轻量)与 YAML(易读),但 XML 在配置与复杂文档领域仍不可替代

XML 用途

XML 的用途

XML 在很多领域发挥着重要作用,尤其在配置与数据交换场景。

1. 配置文件

<!-- Java Web 的 web.xml --%>
<web-app>
  <servlet>
    <servlet-name>HelloServlet</servlet-name>
    <servlet-class>com.example.HelloServlet</servlet-class>
  </servlet>
</web-app>

<!-- Spring 配置 --%>
<beans>
  <bean id="userService" class="com.example.UserService"/>
</beans>

2. 数据交换

<!-- SOAP Web Service 请求 --%>
<soap:Envelope>
  <soap:Body>
    <getPrice>
      <productId>1001</productId>
    </getPrice>
  </soap:Body>
</soap:Envelope>

<!-- RSS 订阅 --%>
<rss version="2.0">
  <channel>
    <title>新闻频道</title>
    <item><title>今日头条</title></item>
  </channel>
</rss>

3. 图形与文档

<!-- SVG 矢量图 --%>
<svg width="100" height="100">
  <circle cx="50" cy="50" r="40" fill="red"/>
</svg>

<!-- 文档:Office Open XML / EPUB / XHTML --%>

4. 数据库

<!-- MySQL 导入导出 --%>
<mysqldump xmlns:xsi="...">
  <database name="shop">
    <table_data name="products">
      <row><field name="id">1</field></row>
    </table_data>
  </database>
</mysqldump>

5. 移动开发

Android 布局与资源文件:
res/layout/activity_main.xml
res/values/strings.xml
AndroidManifest.xml

XML 树结构

XML 树结构

XML 文档以树形结构组织,从根元素开始,层层嵌套形成父子关系。

树形结构示例

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>                          <!-- 根元素 --%>
  <book>                             <!-- 子元素 --%>
    <title>XML 教程</title>         <!-- 叶子元素 --%>
    <author>张三</author>
    <price>59</price>
  </book>
  <book>
    <title>HTML 教程</title>
    <author>李四</author>
    <price>49</price>
  </book>
</bookstore>

树结构解读

bookstore       → 根元素(root),文档只有一个根
book            → bookstore 的子元素(children)
title/author/price → book 的子元素
XML 教程        → 文本节点
bookstore 是 book 的父元素(parent)
book 之间是兄弟元素(sibling)

文档树:
bookstore
  ├── book
  │    ├── title → "XML 教程"
  │    ├── author → "张三"
  │    └── price → "59"
  └── book
       ├── title → "HTML 教程"
       ├── author → "李四"
       └── price → "49"

术语

根元素(Root):  文档最外层元素,唯一
父元素(Parent): 包含其他元素的元素
子元素(Child):  被包含的元素
兄弟(Sibling):  同父元素下的元素
节点(Node):    元素、属性、文本等的统称
叶节点(Leaf):  无子元素的元素

树的遍历

// Java DOM 遍历示例
NodeList books = doc.getElementsByTagName("book");
for (int i = 0; i < books.getLength(); i++) {
    Element book = (Element) books.item(i);
    String title = book.getElementsByTagName("title").item(0).getTextContent();
    System.out.println(title);
}

XML 语法

XML 语法规则

XML 语法严格,任何错误都会导致文档无法解析。

1. XML 声明(可选但推荐)

<?xml version="1.0" encoding="UTF-8"?>
<!-- version:版本,必须
     encoding:编码,建议 UTF-8 --%>

2. 必须有根元素

<!-- 错误:两个根元素 --%>
<a>1</a>
<b>2</b>

<!-- 正确:一个根包裹 --%>
<root>
  <a>1</a>
  <b>2</b>
</root>

3. 标签必须闭合

<!-- 错误 --%>
<name>张三

<!-- 正确 --%>
<name>张三</name>

<!-- 自闭合(无内容) --%>
<img src="a.jpg"/>

4. 大小写敏感

<!-- 错误:标签大小写不匹配 --%>
<Name>张三<name>

<!-- 正确 --%>
<name>张三</name>

5. 正确嵌套

<!-- 错误:交叉嵌套 --%>
<a><b>内容</a></b>

<!-- 正确 --%>
<a><b>内容</b></a>

6. 属性值必须加引号

<!-- 错误 --%>
<person age=28>

<!-- 正确 --%>
<person age="28">
<person age='28'>   <!-- 单引号也可 --%>

7. 特殊字符转义

&lt;    <
&gt;    >
&amp;   &
&apos;  '
&quot;  "

<!-- 示例 --%>
<msg>a &lt; b &amp;&amp; c &gt; d</msg>

8. 注释

<!-- 这是注释 -->
<!-- 注释不能嵌套 -->

XML 元素

XML 元素

元素是 XML 文档的基本构成单位,由开始标签、内容、结束标签组成。

元素结构

<tagname>内容</tagname>

<!-- 空元素(自闭合) --%>
<br/>
<img src="photo.jpg"/>

元素命名规则

1. 名称区分大小写
2. 不能以数字或标点开头
3. 不能包含空格
4. 不能以 "xml" 开头(保留)
5. 避免使用冒号(:)

合法:  <name> <user_name> <userName> <价格>
非法:  <1name> <name name> <xml-data>

元素内容类型

<!-- 文本内容 --%>
<title>XML 教程</title>

<!-- 子元素 --%>
<book>
  <title>XML</title>
</book>

<!-- 混合内容 --%>
<p>文本 <b>加粗</b> 更多文本</p>

<!-- 空元素 --%>
<line-break/>

元素 vs 属性

<!-- 属性方式 --%>
<person name="张三" age="28" gender="男"/>

<!-- 元素方式 --%>
<person>
  <name>张三</name>
  <age>28</age>
  <gender>男</gender>
</person>

经验:数据本身用元素,元数据用属性

使用建议

1. 元素名称要有意义、描述性
2. 保持命名风格一致(全小写+下划线 或 驼峰)
3. 属性用于补充信息,复杂数据用子元素
4. 不要用空格做格式,用标签结构化

XML 属性

XML 属性

属性(Attribute)是元素上附带的名称-值对,提供元素的补充信息。

属性语法

<element attribute="value">
<!-- 多个属性用空格分隔 --%>
<book id="b1" category="编程" lang="zh">
  <title>XML 教程</title>
</book>

属性规则

1. 属性值必须加引号(单双均可)
2. 属性名不能重复
3. 属性名遵循元素命名规则
4. 属性不能包含多个值(可用空格分隔模拟)

属性 vs 子元素的选择

<!-- 属性:标识符、分类、少量元数据 --%>
<book id="1001" category="编程"/>

<!-- 子元素:具体数据内容 --%>
<book>
  <title>XML 教程</title>
  <author>张三</author>
  <price>59</price>
</book>

访问属性

// Java DOM
Element book = (Element) list.item(0);
String id = book.getAttribute("id");
String category = book.getAttribute("category");

// Python ElementTree
import xml.etree.ElementTree as ET
tree = ET.parse("books.xml")
root = tree.getroot()
for book in root.iter("book"):
    print(book.get("id"), book.get("category"))

何时使用属性

1. 唯一标识(id)
2. 分类标记(category)
3. 语言(lang)
4. 单位/格式等元信息
5. 状态标记(active="true")

注意:不要把所有数据都放属性,大文本用子元素

XML 验证

XML 验证

格式正确(Well-formed)只是基本要求,符合约束(Valid)才是完整标准。XML 验证使用 DTD 或 XML Schema。

格式正确 vs 有效

Well-formed(格式正确):
  - 标签闭合、嵌套正确
  - 属性加引号
  - 有根元素
  - 特殊字符转义

Valid(有效):
  - 符合 DTD 或 Schema 定义的
    元素结构、属性、数据类型

什么是 DTD

DTD(Document Type Definition)定义文档结构:

<!ELEMENT bookstore (book+)>
<!ELEMENT book (title, author, price)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ATTLIST book category CDATA #REQUIRED>
<!-- 文档中引用 --%>
<?xml version="1.0"?>
<!DOCTYPE bookstore SYSTEM "bookstore.dtd">
<bookstore>...</bookstore>

什么是 XML Schema(XSD)

XML Schema 是 DTD 的现代替代,功能更强:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="bookstore">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="book" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="title" type="xs:string"/>
              <xs:element name="price" type="xs:decimal"/>
            </xs:sequence>
            <xs:attribute name="category" type="xs:string" use="required"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

验证工具

1. 在线验证器(xmllint 等)
2. IDE(IntelliJ/Eclipse 内置验证)
3. Java JAXP 编程验证
4. Python lxml 验证
# 命令行验证
xmllint --valid --noout books.xml

XML 验证器

XML 验证器

验证器检查 XML 文档是否格式正确、是否符合 DTD/Schema 约束。

在线验证

常见在线 XML 验证工具:
1. w3schools XML Validator
2. xmlvalidator.org
3. freeformatter.com/xml-validator
4. 各类 JSON↔XML 转换工具附带的校验功能

命令行工具(xmllint)

# 检查格式是否正确
xmllint --noout file.xml

# 使用 DTD 验证
xmllint --valid --noout file.xml

# 使用 XSD 验证
xmllint --schema schema.xsd --noout file.xml

# 格式化美化
xmllint --format file.xml

Python 验证(lxml)

pip install lxml

from lxml import etree

# 格式检查
try:
    tree = etree.parse("data.xml")
    print("格式正确")
except etree.XMLSyntaxError as e:
    print("格式错误:", e)

# XSD 验证
schema = etree.XMLSchema(etree.parse("schema.xsd"))
if schema.validate(tree):
    print("验证通过")
else:
    print("验证失败:", schema.error_log)

Java 验证(JAXP)

import javax.xml.XMLConstants;
import javax.xml.validation.*;
import javax.xml.transform.stream.StreamSource;

SchemaFactory factory = SchemaFactory.newInstance(
    XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new StreamSource("schema.xsd"));
Validator validator = schema.newValidator();
try {
    validator.validate(new StreamSource("data.xml"));
    System.out.println("验证通过");
} catch (Exception e) {
    System.out.println("验证失败: " + e.getMessage());
}

IDE 内置验证

1. VS Code 安装 XML 插件(自动校验)
2. IntelliJ IDEA 自带 XML 校验
3. Eclipse XML 编辑器实时校验
4. 错误提示:红线 + 问题面板

XML 查看

XML 查看方式

查看 XML 有浏览器直接打开、编辑器美化、格式化工具等多种方式。

1. 浏览器查看

现代浏览器(Chrome/Firefox/Edge)直接打开 .xml 文件:
- 自动着色(标签、属性、文本)
- 树形折叠显示
- 错误时提示解析失败位置

拖拽 xml 文件到浏览器即可

2. 代码编辑器

VS Code:
  - 内置 XML 高亮
  - 安装 XML Tools 插件(格式化、校验、XPath)

IntelliJ IDEA / Eclipse:
  - 自动缩进与高亮
  - 大纲视图显示树结构
  - 校验与补全

3. 格式化美化

# 命令行
xmllint --format data.xml

# Python
import xml.dom.minidom
pretty = xml.dom.minidom.parse("data.xml").toprettyxml(indent="  ")
print(pretty)

# 在线工具
freeformatter.com / codebeautify.org 等

4. 查看 XML 内容的程序方式

# Python 快速查看
import xml.etree.ElementTree as ET
tree = ET.parse("data.xml")
root = tree.getroot()
print(ET.tostring(root, encoding="unicode"))

5. 数据可视化查看

复杂 XML 数据可以:
- 转 JSON 用 JSON 工具查看
- 用 XSLT 转 HTML 表格查看
- 用 XML 数据库工具(如 BaseX)浏览
- 用 IDE 的可视化编辑器

XML CSS

XML CSS 样式

使用 CSS 可以为 XML 文档添加显示样式,让浏览器呈现可读的排版效果。

1. XML 文件关联 CSS

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="style.css"?>
<bookstore>
  <book>
    <title>XML 教程</title>
    <author>张三</author>
  </book>
</bookstore>

2. 编写 CSS

/* style.css */
bookstore {
  display: block;
  font-family: sans-serif;
  padding: 20px;
  max-width: 600px;
}

book {
  display: block;
  border: 1px solid #ccc;
  margin: 10px 0;
  padding: 10px;
  background: #f9f9f9;
}

title {
  display: block;
  font-size: 20px;
  font-weight: bold;
  color: #333;
}

author {
  display: block;
  color: #666;
  margin-top: 5px;
}

price::before {
  content: "价格: ";
  font-weight: bold;
}

3. 浏览器效果

默认情况下浏览器把 XML 显示为折叠的树
关联 CSS 后:
  - 按 CSS 规则渲染元素
  - 可以布局、着色、控制显示隐藏
  - 数据文档变成可读的排版页面

4. 内联样式

<?xml-stylesheet type="text/css"?>
<root>
  <item style="display:block;color:red;">内容</item>
</root>

5. CSS vs XSLT

CSS: 适合简单样式、元素定位、颜色字体
XSLT: 可以重新组织结构、排序、过滤、生成新文档

简单美化 → CSS
复杂转换(排序/过滤/重组) → XSLT

XML XSLT

XML XSLT 转换

XSLT(eXtensible Stylesheet Language Transformations)把 XML 转换为其他格式(HTML、XML、文本),是 XML 最强大的应用之一。

1. XSLT 基本结构

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/">
    <html>
      <body>
        <h2>图书列表</h2>
        <xsl:apply-templates select="bookstore/book"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="book">
    <p>
      <xsl:value-of select="title"/> -
      <xsl:value-of select="author"/>
    </p>
  </xsl:template>

</xsl:stylesheet>

2. XML 关联 XSLT

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="books.xsl"?>
<bookstore>...</bookstore>
<!-- 浏览器打开 XML 即自动应用转换 --%>

3. 常用 XSLT 元素

<xsl:template match="...">  模板(匹配节点)
<xsl:value-of select="..."> 取值
<xsl:apply-templates select="..."> 应用模板
<xsl:for-each select="..."> 循环
<xsl:if test="...">         条件
<xsl:choose>                多分支
<xsl:sort select="...">     排序
<xsl:attribute name="...">  属性

4. 排序与过滤

<xsl:for-each select="bookstore/book">
  <xsl:sort select="price" data-type="number" order="desc"/>
  <p>
    <xsl:value-of select="title"/>:
    <xsl:value-of select="price"/>
  </p>
</xsl:for-each>

<!-- 过滤:只显示价格 > 50 的书 --%>
<xsl:for-each select="bookstore/book[price > 50]">...</xsl:for-each>

5. 程序执行 XSLT

# Python lxml
from lxml import etree

xml = etree.parse("data.xml")
xslt = etree.parse("style.xsl")
transform = etree.XSLT(xslt)
result = transform(xml)
print(str(result))

# Java
TransformerFactory.newInstance()
    .newTransformer(new StreamSource("style.xsl"))
    .transform(new StreamSource("data.xml"),
               new StreamResult(System.out));

XML HTTP Request

XML HTTP Request(AJAX 获取 XML)

XMLHttpRequest(XHR)是浏览器发起 HTTP 请求的 API,经典 AJAX 技术,常用于异步获取 XML/JSON 数据。

1. 原生 XHR 请求 XML

function loadXML() {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "data.xml", true);

  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
      // 1. 作为 XML 文档解析
      var xmlDoc = xhr.responseXML;
      var titles = xmlDoc.getElementsByTagName("title");
      for (var i = 0; i < titles.length; i++) {
        console.log(titles[i].textContent);
      }

      // 2. 或作为文本
      var text = xhr.responseText;
      document.getElementById("result").innerHTML = text;
    }
  };
  xhr.send();
}

2. 服务端返回 XML

// Java Servlet
response.setContentType("application/xml;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<?xml version='1.0' encoding='UTF-8'?>");
out.println("<books>");
out.println("  <book><title>XML 教程</title></book>");
out.println("</books>");

// Python Flask
@app.route("/data")
def data():
    xml = "<?xml version='1.0'?><books>...</books>"
    return Response(xml, mimetype="application/xml")

3. fetch 方式(现代)

fetch("data.xml")
  .then(function (resp) { return resp.text(); })
  .then(function (xmlText) {
    var parser = new DOMParser();
    var xmlDoc = parser.parseFromString(xmlText, "text/xml");
    var titles = xmlDoc.getElementsByTagName("title");
    for (var i = 0; i < titles.length; i++) {
      console.log(titles[i].textContent);
    }
  });

4. 表单提交(XHR FormData)

var xhr = new XMLHttpRequest();
xhr.open("POST", "search", true);
xhr.setRequestHeader("Content-Type",
  "application/x-www-form-urlencoded");
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    // 解析返回的 XML
  }
};
xhr.send("keyword=XML");

5. XHR vs fetch

XHR:   老 API,回调风格
fetch: 新 API,Promise 风格,更简洁
两者都能获取 XML/JSON 数据
现代项目优先 fetch,兼容老环境用 XHR

XML 解析器

XML 解析器

解析器把 XML 文本转换为程序可操作的结构,主流解析方式有 DOM、SAX、StAX。

1. DOM 解析(文档对象模型)

特点:
- 一次性加载整个文档为内存树
- 支持任意读写、随机访问
- 适合中小文档

Java DOM:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc = factory.newDocumentBuilder().parse("data.xml");
NodeList list = doc.getElementsByTagName("title");

Python ElementTree(DOM 风格):
import xml.etree.ElementTree as ET
tree = ET.parse("data.xml")
for book in tree.iter("book"):
    print(book.find("title").text)

2. SAX 解析(流式)

特点:
- 逐事件读取,内存占用小
- 只能顺序读取
- 适合超大文档

Java SAX:
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse("data.xml", new DefaultHandler() {
    public void startElement(String uri, String local, String qName,
                             Attributes attrs) {
        if (qName.equals("title")) {
            // 遇到 title 开始标签
        }
    }
});

3. StAX 解析(拉式)

特点:
- 流式但由程序控制拉取
- 兼具 DOM 的易用与 SAX 的低内存

Java StAX:
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(
    new FileInputStream("data.xml"));
while (reader.hasNext()) {
    int event = reader.next();
    if (event == XMLStreamConstants.START_ELEMENT) {
        System.out.println(reader.getLocalName());
    }
}

4. 解析器选择

文档较小、需要修改    → DOM
文档超大、只读取      → SAX
大文档、需要控制流    → StAX
脚本语言快速处理      → Python ElementTree / lxml

5. 解析错误处理

// Java
try {
    Document doc = builder.parse("data.xml");
} catch (SAXParseException e) {
    System.out.println("行 " + e.getLineNumber() + ": " + e.getMessage());
} catch (Exception e) {
    e.printStackTrace();
}

XML DOM

XML DOM(文档对象模型)

DOM 把 XML 文档表示为内存中的节点树,提供标准 API 进行增删改查。

1. DOM 节点类型

Document     文档根
Element      元素节点
Attribute    属性节点
Text         文本节点
Comment      注释节点

2. Java DOM 读取

import javax.xml.parsers.*;
import org.w3c.dom.*;

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc = factory.newDocumentBuilder().parse("books.xml");

// 根元素
Element root = doc.getDocumentElement();
System.out.println("根元素: " + root.getTagName());

// 获取所有 book
NodeList books = doc.getElementsByTagName("book");
for (int i = 0; i < books.getLength(); i++) {
    Element book = (Element) books.item(i);
    String id = book.getAttribute("id");
    String title = book.getElementsByTagName("title").item(0).getTextContent();
    System.out.println(id + ": " + title);
}

3. Java DOM 创建与修改

DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();

// 创建元素
Element root = doc.createElement("bookstore");
doc.appendChild(root);

Element book = doc.createElement("book");
book.setAttribute("id", "1001");
root.appendChild(book);

Element title = doc.createElement("title");
title.setTextContent("新书标题");
book.appendChild(title);

// 保存
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(doc), new StreamResult("out.xml"));

4. JavaScript DOM 解析

var parser = new DOMParser();
var xmlDoc = parser.parseFromString(xmlText, "text/xml");

// 查询
var titles = xmlDoc.getElementsByTagName("title");
var first = xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;

// 修改
xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue = "新标题";

// 创建
var newBook = xmlDoc.createElement("book");
xmlDoc.documentElement.appendChild(newBook);

5. Python DOM(minidom)

from xml.dom import minidom

doc = minidom.parse("books.xml")
books = doc.getElementsByTagName("book")
for book in books:
    title = book.getElementsByTagName("title")[0].firstChild.data
    print(title)

XML/HTML

XML 与 HTML

XML 与 HTML 同属标记语言但定位不同,了解区别与 XHTML 的桥梁作用很重要。

主要区别

XML:
- 描述数据(是什么)
- 标签自定义
- 语法严格(闭合、大小写)
- 区分大小写
- 空格保留

HTML:
- 展示数据(长什么样)
- 标签预定义
- 语法宽松(可省略闭合)
- 不区分大小写
- 空格折叠

XHTML(HTML 的 XML 化)

XHTML 是用 XML 规则编写的 HTML:

<!-- 必须闭合 --%>
<br/> 或 <br></br>
<img src="a.jpg" alt="图"/>

<!-- 属性必须小写加引号 --%>
<input type="text" name="user"/>

XHTML 特点:
- 更严格的 HTML
- 可被 XML 工具处理
- 现代 HTML5 已不再强制 XHTML 语法

HTML5 与 XML

HTML5 语法更宽松:
- 标签可不闭合(li、br)
- 属性值可不加引号
- 大小写不敏感
- 但 HTML5 也是基于 DOM 结构

XML 仍然用于:
- 配置、数据交换、文档格式
- 与 HTML 场景互补

XML 数据嵌入 HTML

<!-- 用模板渲染 --%>
<script id="tmpl" type="text/xml">
  <book><title>XML 教程</title></book>
</script>

<!-- data 属性传递 --%>
<div data-info='{"name":"xml"}'></div>

<!-- 常见做法:后台数据转 JSON 给前端 --%>
<script>
  var data = <%= jsonData %>;
</script>

如何选择

展示内容     → HTML
数据交换     → JSON(轻量)或 XML(标准/复杂结构)
配置文件     → XML(Java 生态)或 YAML
文档格式     → XML(SVG、Office 文档)

XML 应用程序

XML 应用程序

XML 的应用无处不在,从桌面软件到 Web 服务、移动开发。

1. Java 生态配置

<!-- Maven pom.xml --%>
<project>
  <groupId>com.example</groupId>
  <artifactId>myapp</artifactId>
  <version>1.0.0</version>
</project>

<!-- Spring Bean 配置 --%>
<beans>
  <bean id="userService" class="com.example.UserService"/>
</beans>

2. Web 服务

<!-- SOAP 请求 --%>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <getWeather xmlns="http://example.com/ws">
      <city>北京</city>
    </getWeather>
  </soap:Body>
</soap:Envelope>

3. Android 开发

<!-- AndroidManifest.xml --%>
<manifest package="com.example.app">
  <application>
    <activity android:name=".MainActivity"/>
  </application>
</manifest>

<!-- 布局 --%>
<LinearLayout>
  <TextView android:text="Hello"/>
</LinearLayout>

4. 文档格式

SVG 矢量图、XHTML、MathML
Office 文档(docx/xlsx/pptx 本质是 zip 包内的 XML)
EPUB 电子书
RSS/Atom 订阅源
UML 交换格式(XMI)

5. 数据库

MySQL: LOAD XML、EXPORT XML
SQL Server: FOR XML
Oracle: XMLType
NoSQL: eXist、BaseX 等原生 XML 数据库

6. 桌面与系统

Visual Studio 工程文件(.csproj)
WordPress 导出(.xml)
Chrome/VS Code 配置(JSON 化,但 XML 仍常见)
SVG 图标系统

XML 命名空间

XML 命名空间(Namespace)

命名空间用 URI 区分不同来源的标签,避免同名元素冲突。

为什么需要命名空间

<!-- 冲突示例:两个 table 含义不同 --%>
<table>  <!-- HTML 表格 --%>
  <tr><td>数据</td></tr>
</table>
<table>  <!-- 数据库表 --%>
  <name>users</name>
</table>

<!-- 用命名空间区分 --%>
<h:table xmlns:h="http://www.w3.org/TR/html4/">
  <h:tr><h:td>数据</h:td></h:tr>
</h:table>
<f:table xmlns:f="http://example.com/db">
  <f:name>users</f:name>
</f:table>

定义命名空间

使用 xmlns 属性声明:

<?xml version="1.0"?>
<root xmlns:h="http://example.com/html"
      xmlns:f="http://example.com/db">
  <h:table>...</h:table>
  <f:table>...</f:table>
</root>

默认命名空间

<!-- 无前缀的默认命名空间 --%>
<root xmlns="http://example.com/default">
  <child>属于默认命名空间</child>
</root>

命名空间 URI 只是标识

命名空间的 URI 通常不指向实际网页:
- 只是唯一标识符
- 用于区分同名标签
- 常见示例:http://www.w3.org/2001/XMLSchema

在程序中使用

// Java XPath 带命名空间
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
        return "http://example.com/db".equals(prefix) ? prefix : null;
    }
});

// Python lxml 用 {uri}tag 语法
from lxml import etree
root = etree.fromstring(xml_bytes)
ns = {"f": "http://example.com/db"}
elems = root.xpath("//f:table", namespaces=ns)

常用命名空间

XSD:  http://www.w3.org/2001/XMLSchema
XSLT: http://www.w3.org/1999/XSL/Transform
SOAP: http://schemas.xmlsoap.org/soap/envelope/
SVG:  http://www.w3.org/2000/svg

XML CDATA

XML CDATA

CDATA(Character Data)区段中的内容原样输出,不解析其中的特殊字符,适合存放代码、脚本等含大量特殊字符的文本。

问题场景

<!-- 代码中含 < > & 需要逐个转义,很麻烦 --%>
<code>
  if (a &lt; b &amp;&amp; c &gt; d) { ... }
</code>

使用 CDATA

<code><![CDATA[
  if (a < b && c > d) {
    System.out.println("原始内容");
  }
]]></code>

<!-- CDATA 内所有字符原样保留,无需转义 --%>

CDATA 语法

<![CDATA[ 内容 ]]

规则:
1. 内容中的 < > & " ' 均不需转义
2. 不能包含 "]]>"(这是结束标记)
3. 空格与换行原样保留

常见用途

1. 存放代码片段(HTML/JS/CSS/SQL)
2. 存放 XML 片段(作为文本)
3. 存放含大量特殊字符的文本

<!-- 存放 HTML 示例 --%>
<example><![CDATA[
  <div class="box">内容</div>
]]></example>

读取 CDATA

// Java DOM 读取(CDATA 是文本节点)
Element code = (Element) doc.getElementsByTagName("code").item(0);
String content = code.getTextContent();

// Python
text = root.find("code").text
print(text)   // 原始内容

CDATA vs 转义

少量特殊字符 → 直接转义(&lt; 等)
大量特殊字符(代码块) → CDATA 更清晰

注意:CDATA 只影响解析,不改变数据含义
解析后得到的就是原始文本

XML 编码

XML 编码

编码决定字符如何存储,处理不当会导致中文乱码。

声明编码

<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="GB2312"?>
<?xml version="1.0" encoding="ISO-8859-1"?>

encoding 必须与文件实际编码一致,否则解析报错或乱码

常用编码

UTF-8:    国际通用,推荐(默认)
UTF-16:   Unicode 双字节
GB2312:   简体中文
GBK:      中文扩展
ISO-8859-1: 西欧字符(不支持中文)

乱码原因与解决

1. 文件保存为 GBK,声明 UTF-8 → 解析失败/乱码
   解决:声明与实际一致,或统一 UTF-8

2. 读取时未指定编码
   Java: builder 默认按声明读取,通常没问题
   Python: open("data.xml", encoding="utf-8")

3. 网络传输编码
   响应头与 XML 声明一致

程序指定编码

// Java 读取指定编码
InputStream is = new FileInputStream("data.xml");
Document doc = builder.parse(is);   // 按声明编码解析

// Python 读取
import xml.etree.ElementTree as ET
tree = ET.parse("data.xml")   # 自动处理声明编码
# 或指定
with open("data.xml", encoding="utf-8") as f:
    tree = ET.parse(f)

输出编码

// Java 写出指定编码
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
t.transform(new DOMSource(doc), new StreamResult(out));

// Python 写出
ET.ElementTree(root).write("out.xml",
    encoding="UTF-8", xml_declaration=True)

验证编码

# 命令行检查
file data.xml
# data.xml: XML 1.0 document, UTF-8 Unicode text

XML 服务器

XML 服务器端应用

服务器端可以动态生成 XML、接收 XML 数据,实现系统间数据交换。

1. 服务端生成 XML

// Java Servlet 输出 XML
@WebServlet("/api/products")
public class ProductApi extends HttpServlet {
    protected void doGet(...) {
        response.setContentType("application/xml;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println("<?xml version='1.0' encoding='UTF-8'?>");
        out.println("<products>");
        // 从数据库读取
        for (Product p : products) {
            out.println("<product id='" + p.getId() + "'>");
            out.println("<name>" + p.getName() + "</name>");
            out.println("<price>" + p.getPrice() + "</price>");
            out.println("</product>");
        }
        out.println("</products>");
    }
}

2. 服务端接收 XML

// Java 接收客户端提交的 XML
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
    // 读取请求体
    StringBuilder sb = new StringBuilder();
    BufferedReader reader = req.getReader();
    String line;
    while ((line = reader.readLine()) != null) {
        sb.append(line);
    }
    // 解析 XML
    Document doc = DocumentBuilderFactory.newInstance()
        .newDocumentBuilder()
        .parse(new ByteArrayInputStream(
            sb.toString().getBytes("UTF-8")));
    // 处理...
}

3. 客户端提交 XML(AJAX)

var xmlData = "<order><productId>1001</productId>" +
              "<quantity>2</quantity></order>";

var xhr = new XMLHttpRequest();
xhr.open("POST", "order", true);
xhr.setRequestHeader("Content-Type", "application/xml");
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
    // 处理响应
  }
};
xhr.send(xmlData);

4. 数据库生成 XML

-- MySQL 导出 XML
SELECT id, name, price FROM products
INTO OUTFILE '/tmp/products.xml'
ROWS FROM XML;

-- SQL Server 生成 XML
SELECT * FROM products FOR XML AUTO, ELEMENTS;

5. 框架支持

Java: JAXB(对象↔XML 自动映射)
      jaxb-api

@XmlRootElement
public class Product {
    @XmlElement public String name;
    @XmlAttribute public int id;
}

// 序列化
JAXBContext ctx = JAXBContext.newInstance(Product.class);
Marshaller m = ctx.createMarshaller();
m.marshal(product, out);

XML DOM 高级

XML DOM 高级操作

深入掌握 DOM 的高级用法:XPath 查询、遍历、属性操作与批量处理。

1. XPath 查询

// Java
XPath xpath = XPathFactory.newInstance().newXPath();

// 选择所有 title
NodeList titles = (NodeList) xpath.evaluate("//title", doc,
    XPathConstants.NODESET);

// 带条件:category 属性为编程的书
NodeList books = (NodeList) xpath.evaluate(
    "//book[@category='编程']", doc, XPathConstants.NODESET);

// 取文本
String first = (String) xpath.evaluate(
    "//book[1]/title/text()", doc, XPathConstants.STRING);

2. XPath 常用表达式

/bookstore            根下的 bookstore
//book               文档中所有 book
/bookstore/book[1]   第一个 book
/bookstore/book[last()] 最后一个
//book[@id]          有 id 属性的
//book[price > 50]   价格大于 50
//book/title/text()  所有 title 文本

3. 遍历与修改

// Java 遍历并修改
NodeList books = doc.getElementsByTagName("book");
for (int i = 0; i < books.getLength(); i++) {
    Element book = (Element) books.item(i);
    // 改属性
    book.setAttribute("updated", "true");
    // 改文本
    Node title = book.getElementsByTagName("title").item(0);
    title.setTextContent(title.getTextContent() + " (第2版)");
    // 删除
    if (book.getAttribute("id").equals("999")) {
        book.getParentNode().removeChild(book);
    }
}

4. 创建新节点

// Java
Element newBook = doc.createElement("book");
newBook.setAttribute("id", "1002");

Element title = doc.createElement("title");
title.setTextContent("XML 高级教程");
newBook.appendChild(title);

// 插入到指定位置
Element root = doc.getDocumentElement();
root.insertBefore(newBook, root.getFirstChild());   // 最前
// root.appendChild(newBook);                        // 最后

5. 命名空间感知

// 处理带命名空间的文档
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document doc = factory.newDocumentBuilder().parse("data.xml");

// 用 getElementsByTagNameNS
NodeList nodes = doc.getElementsByTagNameNS(
    "http://example.com/db", "product");

6. 大文档优化

DOM 一次性加载,超大文档内存不足:
1. 用 SAX 流式处理
2. 或 StAX 拉式解析
3. 或 XPath 分段查询(XQuery 工具)

XML 注意事项

XML 使用注意事项

使用 XML 时需要注意语法细节、安全性与性能问题。

1. 语法常见错误

1. 标签不闭合
2. 大小写不一致
3. 属性值未加引号
4. 特殊字符未转义(< &)
5. 根元素不止一个
6. 注释嵌套
7. 元素名以数字开头

2. 安全注意事项

1. XXE(XML External Entity)攻击:
   恶意文档读取本地文件/发起内网请求

   Java 解析时禁用外部实体:
   factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
   factory.setFeature("http://xml.org/sax/features/external-general-entities", false);

   Python 用 defusedxml 替代标准库:
   pip install defusedxml

2. 不要信任外部 XML 输入
3. 限制解析文档大小,防 DoS

3. 性能注意事项

1. 解析大文件用 SAX/StAX,不用 DOM
2. 避免深层嵌套(影响解析效率)
3. 属性不要存放大量文本
4. 频繁转换(字符串↔对象)用 JAXB 等自动映射
5. 网络传输可用压缩

4. 设计注意事项

1. 命名统一、有意义
2. 为重要文档定义 DTD/Schema
3. 中文内容统一 UTF-8
4. 数据与元数据分层清晰
5. 版本化设计(兼容演进)

5. 工具检查清单

开发前:选解析器(DOM/SAX/StAX)
开发中:格式校验、Schema 校验
上线前:安全检查(XXE)、性能测试
维护时:文档注释、Schema 版本管理

XML 技术

XML 相关技术体系

围绕 XML 形成了一整套技术标准,了解全景有助于选型。

核心技术

XML         基础标记语言
DTD         文档类型定义(约束结构)
XML Schema(XSD)  现代约束(数据类型更强)
XPath       节点定位语言
XSLT        转换语言(XML→HTML/XML)
XQuery      查询语言(类似 SQL)
XLink       链接规范
XPointer    指针定位
DOM / SAX / StAX  解析 API
CSS         显示样式(XML 也可用)
Namespaces  命名空间

XML 家族的用途划分

定义结构:   DTD / XML Schema
定位数据:   XPath / XQuery
转换展示:   XSLT / CSS
传输协议:   SOAP / XML-RPC
解析访问:   DOM / SAX / StAX
特殊文档:   SVG / MathML / RSS / XHTML

XQuery 简介

// 类似 SQL 的 XML 查询
for $book in doc("books.xml")//book
where $book/price > 50
order by $book/price
return $book/title

XPath 再回顾

// 定位
/bookstore/book[2]/title
//book[@category='编程']
count(//book)    元素数量
sum(//book/price) 求和

技术选型建议

简单配置     → XML + DTD 或直接用 JSON/YAML
数据交换     → JSON 为主,标准协议用 XML
复杂文档     → XML + Schema + XSLT
查询分析     → XQuery / BaseX
Web 服务     → SOAP(XML)或 REST(JSON)

XML 现实案例

XML 现实案例

通过真实案例理解 XML 如何解决实际问题。

案例 1:配置文件管理(Java Web)

场景:Web 应用配置数据库连接与过滤器

<!-- web.xml --%>
<web-app>
  <context-param>
    <param-name>jdbcUrl</param-name>
    <param-value>jdbc:mysql://localhost/shop</param-value>
  </context-param>
  <filter>
    <filter-name>auth</filter-name>
    <filter-class>com.example.AuthFilter</filter-class>
  </filter>
</web-app>

收益:改配置无需改代码,重启即生效

案例 2:系统间数据交换(订单同步)

场景:ERP 系统向电商平台推送订单

<order id="20260818001">
  <customer>
    <name>张三</name>
    <phone>13800000000</phone>
  </customer>
  <items>
    <item>
      <sku>SKU-001</sku>
      <qty>2</qty>
      <price>99.00</price>
    </item>
  </items>
  <total>198.00</total>
</order>

收益:结构标准化,双方约定 Schema 即可对接

案例 3:RSS 新闻订阅

<rss version="2.0">
  <channel>
    <title>技术新闻</title>
    <item>
      <title>XML 教程上线</title>
      <link>http://example.com/xml</link>
      <pubDate>Tue, 18 Aug 2026 09:00:00 GMT</pubDate>
    </item>
  </channel>
</rss>

收益:聚合器解析 RSS 即可展示各站点新闻

案例 4:SVG 图标与图形

<svg width="24" height="24" viewBox="0 0 24 24">
  <path d="M12 2 L2 22 L22 22 Z" fill="#ff5722"/>
</svg>

收益:矢量缩放不失真,可直接嵌入 HTML/程序

XML 编辑器

XML 编辑器

选择合适的编辑器能提升 XML 编写效率,这里介绍主流工具。

1. 通用代码编辑器

VS Code:
  - 内置 XML 高亮与缩进
  - 插件:XML Tools(格式化/XPath/校验)
  - 免费开源,跨平台

IntelliJ IDEA / WebStorm:
  - 智能补全、实时校验
  - 结构化视图
  - 支持 XSD 提示

Eclipse:
  - XML 编辑器 + 大纲视图
  - 支持 DTD/XSD 验证

2. 专用 XML 工具

XMLSpy(Altova):  企业级,可视化编辑与 Schema 设计
Oxygen XML:      强大的 XML 编辑器(含 XSLT 调试)
XML Notepad:     Windows 轻量树形编辑器
BaseX:           XML 数据库 + 查询调试
XMLBuddy:        Eclipse 插件(较老)

3. 在线工具

formatter:  格式化与校验
validator:  DTD/Schema 验证
XPath tester: 测试 XPath 表达式
XSLT tester:  测试转换
JSON↔XML 转换工具

4. 编辑器功能对比

日常编辑   → VS Code + XML Tools(推荐)
IDE 集成   → IntelliJ / Eclipse
复杂 Schema → Oxygen / XMLSpy
快速校验   → 在线工具或 xmllint

5. 高效编辑技巧

1. 利用格式化快捷键(Alt+Shift+F VS Code)
2. 使用 XSD 获取智能提示
3. 折叠展开节点管理大文档
4. 用 Emmet/片段加速输入
5. 写完立即校验,避免批量错误

XML E4X

XML E4X

E4X(ECMAScript for XML)是把 XML 作为 JavaScript 原生数据类型的扩展,极大简化 XML 操作,但已被现代浏览器逐步放弃。

E4X 简介

E4X 让 JS 直接书写与操作 XML:
- XML 是原生数据类型
- 用点号访问元素
- 用 @ 访问属性
- 不再需要 DOM 繁琐调用

E4X 语法示例(当时的标准)

// 直接创建 XML
var books = <books>
  <book id="1"><title>XML 教程</title></book>
  <book id="2"><title>HTML 教程</title></book>
</books>;

// 访问元素
var first = books.book[0].title;      // XML 教程
// 访问属性
var id = books.book[0].@id;           // 1
// 遍历
for each (var book in books.book) {
  print(book.title);
}

E4X 的兴衰

推出:Firefox 早期支持
问题:语法特殊、性能一般、跨浏览器支持差
结局:现代浏览器与 Node.js 均不再支持
替代:JSON 成为 JS 数据交换事实标准

学习意义:了解 XML 在 JS 历史中的演进,不再使用

现代 JS 处理 XML

// DOMParser 解析
var doc = new DOMParser().parseFromString(xmlText, "text/xml");

// 查询
var titles = doc.getElementsByTagName("title");
var first = titles[0].textContent;

// XPath
var result = document.evaluate("//book[@id='1']/title",
    doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
console.log(result.singleNodeValue.textContent);

结论

E4X 是历史产物,了解即可。
现代 XML 处理:
- 前端:DOMParser + XPath 或转 JSON
- 后端:各语言原生 XML 库

XML 总结

XML 总结

本教程系统讲解了 XML 的核心知识,下面做整体回顾。

知识体系回顾

基础概念:  XML 是什么、用途、树结构
语法:      声明、元素、属性、转义、命名空间
约束:      DTD、XML Schema、验证器
解析:      DOM、SAX、StAX、XPath
转换:      XSLT、CSS 显示
应用:      配置文件、数据交换、Web 服务、SVG
安全:      XXE 防护、编码处理
工具:      编辑器、校验器、格式化工具

核心要点

1. 格式正确是前提,符合 Schema 是标准
2. 元素表达数据,属性表达元数据
3. 命名空间解决同名冲突
4. CDATA 存放原始文本(代码)
5. 统一 UTF-8 编码防乱码
6. 解析外部 XML 务必防 XXE

选择建议

需要严格结构约束 → XML + Schema
简单数据交换     → JSON
配置文件         → XML(Java 生态)或 YAML
文档/图形格式    → XML(SVG、Office)
跨语言服务       → SOAP(XML)或 REST(JSON)

下一步学习

1. 深入学习 XSLT 与 XPath
2. 掌握 JAXB/lxml 等解析库
3. 了解 XML 数据库(BaseX)
4. 实践:定义自己的 Schema 并验证
5. 对比学习 JSON/YAML 语法

XML 实例

XML 综合实例

通过一个"学生信息管理"实例,串联 XML 的创建、验证、解析、展示全流程。

1. XML 数据文件(students.xml)

<?xml version="1.0" encoding="UTF-8"?>
<students>
  <student id="s001">
    <name>张三</name>
    <age>18</age>
    <grade>高一</grade>
    <courses>
      <course score="95">数学</course>
      <course score="88">语文</course>
    </courses>
  </student>
  <student id="s002">
    <name>李四</name>
    <age>17</age>
    <grade>高一</grade>
    <courses>
      <course score="82">数学</course>
      <course score="91">语文</course>
    </courses>
  </student>
</students>

2. Schema 定义(students.xsd)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="students">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="student" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="name" type="xs:string"/>
              <xs:element name="age" type="xs:int"/>
              <xs:element name="grade" type="xs:string"/>
            </xs:sequence>
            <xs:attribute name="id" type="xs:string" use="required"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

3. Python 解析与统计

import xml.etree.ElementTree as ET

tree = ET.parse("students.xml")
root = tree.getroot()

print("学生数:", len(root.findall("student")))

for stu in root.iter("student"):
    name = stu.find("name").text
    age = stu.find("age").text
    courses = stu.findall("courses/course")
    total = sum(int(c.get("score")) for c in courses)
    avg = total / len(courses)
    print(f"{name}({age}岁) 平均分: {avg:.1f}")

4. XSLT 转 HTML 展示

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html><body>
      <h2>学生列表</h2>
      <table border="1">
        <tr><th>姓名</th><th>年龄</th><th>班级</th></tr>
        <xsl:for-each select="students/student">
          <tr>
            <td><xsl:value-of select="name"/></td>
            <td><xsl:value-of select="age"/></td>
            <td><xsl:value-of select="grade"/></td>
          </tr>
        </xsl:for-each>
      </table>
    </body></html>
  </xsl:template>
</xsl:stylesheet>

5. 完整流程

创建 XML → Schema 校验 → 解析 → 查询统计 → XSLT 展示
这就是 XML 在企业应用中的典型工作流

XML 常见问题

XML 常见问题(FAQ)

汇总 XML 学习和使用中最常遇到的问题与解答。

Q1: XML 和 HTML 有什么区别?

XML 描述数据(自定义标签、严格语法)
HTML 展示数据(预定义标签、宽松语法)
XML 关心"数据是什么",HTML 关心"长什么样"

Q2: XML 会被 JSON 取代吗?

不会完全取代:
- JSON 更适合 API 轻量数据交换
- XML 在配置文件、复杂文档、SOAP、SVG 等领域仍占主导
- 两者各有所长,按场景选择

Q3: 为什么我的 XML 解析报错?

常见原因:
1. 标签未闭合或嵌套错误
2. 大小写不匹配
3. 属性值未加引号
4. 特殊字符未转义(< &)
5. 编码声明与实际不符
6. 根元素重复
用验证器检查即可定位

Q4: 中文乱码怎么办?

1. 文件保存为 UTF-8
2. 声明 encoding="UTF-8"
3. 解析时指定正确编码
4. 网络传输时 Content-Type 一致

Q5: 什么是 XXE 攻击?

XML External Entity:
恶意 XML 利用外部实体读取本地文件或发起内网请求

防护:
- 禁用 DTD/外部实体
- 用 defusedxml(Python)
- 只解析可信来源的 XML

Q6: DOM、SAX、StAX 怎么选?

小文档+需要修改   → DOM
超大文档+只读取   → SAX
大文档+流式控制   → StAX
脚本快速处理     → ElementTree/lxml

Q7: 属性还是子元素?

经验法则:
- 标识符、分类、元数据 → 属性
- 数据内容、大文本     → 子元素
- 复杂结构            → 子元素嵌套

Q8: 需要 DTD 还是 Schema?

新项目优先 XML Schema(XSD):
- 支持数据类型(整数、日期)
- 支持命名空间
- 可扩展、可复用
DTD 用于兼容旧系统

Q9: 怎么快速美化 XML?

xmllint --format data.xml
VS Code 插件格式化
Python: minidom.toprettyxml()

Q10: XML 性能慢怎么办?

1. 流式解析(SAX/StAX)
2. 减少深层嵌套
3. 避免不必要的字符串转换
4. 网络传输压缩
5. 缓存解析结果
第 1 / 30 节