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
| 特性 | XML | HTML |
|---|---|---|
| 用途 | 存储/传输数据 | 显示数据 |
| 标签 | 自定义 | 预定义 |
| 大小写 | 区分 | 不区分 |
| 结束标签 | 必须有 | 可省略 |
| 空格 | 保留 | 折叠 |
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. 特殊字符转义
< <
> >
& &
' '
" "
<!-- 示例 --%>
<msg>a < b && c > 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 < b && c > 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 转义
少量特殊字符 → 直接转义(< 等)
大量特殊字符(代码块) → 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. 缓存解析结果