XML 详细教程
XML(eXtensible Markup Language)是一种可扩展标记语言,用于存储和传输数据。它被设计为具有自我描述性,是许多应用程序和协议的基础。
1. XML 基础
1.1 XML 文档结构
一个完整的XML文档包含以下部分:
- XML声明:
<?xml version="1.0" encoding="UTF-8"?>
- 根元素:文档必须有一个唯一的根元素
- 子元素:可以嵌套其他元素
- 属性:元素可以包含属性
- 文本内容:元素可以包含文本
1.2 XML 语法规则
- 所有XML元素必须有闭合标签
- XML标签对大小写敏感
- XML必须正确地嵌套
- XML文档必须有根元素
- XML属性值必须加引号
- 特殊字符需要使用实体引用(如
<
表示<
)
2. XML 示例
2.1 简单XML文档
运行
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="小说">
<title lang="zh">红楼梦</title>
<author>曹雪芹</author>
<year>1791</year>
<price>59.99</price>
</book>
<book category="科技">
<title lang="en">Python编程</title>
<author>Mark Lutz</author>
<year>2013</year>
<price>89.99</price>
</book>
</bookstore>
2.2 带有命名空间的XML
运行
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="http://example.com/furniture">
<h:table>
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>Coffee Table</f:name>
<f:width>80</f:width>
</f:table>
</root>
3. XML 相关技术
3.1 DTD(文档类型定义)
定义XML文档的结构: 运行
<!DOCTYPE bookstore [
<!ELEMENT bookstore (book+)>
<!ELEMENT book (title, author, year, price)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT year (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ATTLIST book category CDATA #REQUIRED>
]>
3.2 XML Schema(XSD)
更强大的XML结构定义方式: 运行
<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="author" type="xs:string"/>
<xs:element name="year" type="xs:integer"/>
<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>
3.3 XPath
用于在XML文档中导航和查询:
/bookstore/book[price>35]/title
3.4 XSLT
XML文档转换语言: 运行
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Bookstore</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Author</th>
</tr>
<xsl:for-each select="bookstore/book">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="author"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
4. 在各语言中使用 XML
4.1 Python 中使用 XML
使用xml.etree.ElementTree:
import xml.etree.ElementTree as ET
# 解析XML
tree = ET.parse('books.xml')
root = tree.getroot()
# 遍历元素
for book in root.findall('book'):
title = book.find('title').text
price = book.find('price').text
print(f"Title: {title}, Price: {price}")
# 创建XML
root = ET.Element("bookstore")
book = ET.SubElement(root, "book", category="科技")
ET.SubElement(book, "title").text = "Python编程"
ET.SubElement(book, "price").text = "89.99"
# 写入文件
tree = ET.ElementTree(root)
tree.write("output.xml", encoding="utf-8", xml_declaration=True)
4.2 Java 中使用 XML
使用DOM解析:
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
// 解析XML
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc = factory.newDocumentBuilder().parse("books.xml");
// 获取所有book元素
NodeList books = doc.getElementsByTagName("book");
for (int i = 0; i < books.getLength(); i++) {
Node book = books.item(i);
NodeList children = book.getChildNodes();
for (int j = 0; j < children.getLength(); j++) {
Node child = children.item(j);
if (child.getNodeType() == Node.ELEMENT_NODE) {
System.out.println(child.getNodeName() + ": " + child.getTextContent());
}
}
}
使用JAXB(Java对象与XML绑定):
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
class Bookstore {
@XmlElement(name = "book")
private List<Book> books;
// getters and setters
}
class Book {
private String title;
private String author;
private int year;
private double price;
@XmlAttribute
private String category;
// getters and setters
}
// 序列化对象到XML
Bookstore bookstore = new Bookstore();
// 添加books...
JAXBContext context = JAXBContext.newInstance(Bookstore.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(bookstore, new File("output.xml"));
5. XML 高级主题
5.1 XML 命名空间
运行
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="http://example.com/furniture">
<h:table>
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
</root>
5.2 XML 签名
运行
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>dGhpcyBpcyBub3QgYSBzaWduYXR1cmU=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>MC0CFFrVLtRlk=...</SignatureValue>
</Signature>
5.3 XQuery
XML查询语言示例: xquery
for $x in doc("books.xml")/bookstore/book
where $x/price>30
order by $x/title
return $x/title
6. XML 最佳实践
- 使用有意义的标签名:使XML文档自描述
- 合理使用属性:属性用于元数据,内容放在元素中
- 保持一致性:在整个文档中使用相同的命名约定
- 使用注释:
<!-- 这是一个注释 -->
- 验证XML:使用DTD或XSD确保结构正确
- 处理特殊字符:使用实体引用(
<
,>
,&
,"
,'
) - 考虑性能:对于大型XML,使用SAX代替DOM
7. XML 常见问题与解决方案
7.1 处理XML中的特殊字符
运行
<description>
<![CDATA[
这是一个包含特殊字符 < > & 的文本
无需转义这些字符
]]>
</description>
7.2 处理XML命名空间
// Java中使用XPath处理命名空间
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document doc = factory.newDocumentBuilder().parse("books.xml");
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
xpath.setNamespaceContext(new NamespaceContext() {
public String getNamespaceURI(String prefix) {
return "http://example.com/books";
}
// 其他方法实现...
});
String title = xpath.evaluate("//b:title", doc);
7.3 大型XML文件处理
# 使用SAX解析大型XML
import xml.sax
class BookHandler(xml.sax.ContentHandler):
def __init__(self):
self.current_data = ""
self.title = ""
def startElement(self, tag, attributes):
self.current_data = tag
def characters(self, content):
if self.current_data == "title":
self.title += content
def endElement(self, tag):
if tag == "title":
print("Title:", self.title.strip())
self.title = ""
self.current_data = ""
parser = xml.sax.make_parser()
handler = BookHandler()
parser.setContentHandler(handler)
parser.parse("large_books.xml")
8. XML 工具推荐
- XML编辑器:
- XMLSpy
- Oxygen XML Editor
- Visual Studio Code(带XML扩展)
- 在线工具:
- 库和框架:
- Python:
xml.etree.ElementTree
,lxml
- Java:
javax.xml
,DOM4J
,JDOM
- JavaScript:
DOMParser
,xml2js
XML作为一种成熟的数据交换格式,在企业应用、文档存储和Web服务中仍然广泛使用。掌握XML及其相关技术对于处理各种遗留系统和标准化数据交换非常重要。
- Python: