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属性值必须加引号
  • 特殊字符需要使用实体引用(如&lt;表示<

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 最佳实践

  1. 使用有意义的标签名:使XML文档自描述
  2. 合理使用属性:属性用于元数据,内容放在元素中
  3. 保持一致性:在整个文档中使用相同的命名约定
  4. 使用注释<!-- 这是一个注释 -->
  5. 验证XML:使用DTD或XSD确保结构正确
  6. 处理特殊字符:使用实体引用(&lt;, &gt;, &amp;, &quot;, &apos;
  7. 考虑性能:对于大型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 工具推荐

  1. XML编辑器
    • XMLSpy
    • Oxygen XML Editor
    • Visual Studio Code(带XML扩展)
  2. 在线工具
  3. 库和框架
    • Python: xml.etree.ElementTree, lxml
    • Java: javax.xml, DOM4J, JDOM
    • JavaScript: DOMParser, xml2js XML作为一种成熟的数据交换格式,在企业应用、文档存储和Web服务中仍然广泛使用。掌握XML及其相关技术对于处理各种遗留系统和标准化数据交换非常重要。









results matching ""

    No results matching ""