XML实用技术第二版:从示例到实践

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:《XML实用技术第二版:从示例到实践》是为具备HTML和JavaScript基础的读者编写,旨在通过示例教学提升XML应用能力。本书详细介绍了XML语言在数据交换、配置文件和文档结构化中的作用,并解释了XML的设计目标、语法结构、命名空间以及元素、属性和文本内容的组成。此外,书中还涵盖了XML的两种主要解析方法DOM和SAX,以及与XSLT和XPath的集成使用,揭示了如何通过XSD进行数据验证。读者将学习创建XML文档、解析XML数据、转换XML格式以及XML在实际开发中的应用。本书内容结合理论和实践,是提升XML相关技能的宝贵资源。

1. XML基础和设计目标

XML(Extensible Markup Language)是一种通用的标记语言,用于在Web上存储和传输数据。其设计目标包括提供一种统一的方法来共享数据结构,并通过简单的语法支持跨平台和跨语言的数据交换。

XML的起源和特点

XML起源于SGML(Standard Generalized Markup Language),是一种更为简化和面向互联网的标记语言。它允许用户定义自己的标签来描述信息,而不像HTML那样标签是预先定义好的。这种灵活性使得XML非常适合于在不同系统间交换数据。

XML文档有以下三个核心特点: 1. 可扩展性:可以定义无限数量的标记来描述信息。 2. 结构性:数据结构清晰,支持复杂的层次化结构。 3. 平台无关性:文本格式的数据易于跨平台共享。

XML设计目标的实现

为了实现这些设计目标,XML制定了严格的设计原则: - 确保可读性,XML文档应便于人类阅读。 - 提供数据结构,使机器能理解数据格式。 - 分离数据内容与数据表现,以适应不同的显示方式。 - 支持国际化,能够表示多种语言的字符。

下一章将详细探讨XML的语法和结构化数据,如何在实际文档中应用这些元素以及它们是如何共同作用以实现上述设计目标的。

2. XML语法和结构化数据

2.1 XML文档结构

2.1.1 XML声明和文档类型定义

XML文档以XML声明开始,它告诉读者文档使用的是XML以及文档的版本号。它还可以包含一个字符编码声明和独立性声明,如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  • version 指定了文档所遵循的XML版本。
  • encoding 指明了文档中使用的字符编码集,如UTF-8、UTF-16等。
  • standalone 可以是“yes”或“no”,表明文档是否独立于外部标识和实体。

紧随XML声明之后,可有文档类型定义(DTD),它用于验证XML文档的结构和语义。DTD可以内联在文档中,或者通过引用外部文件:

<!DOCTYPE rootElement [
<!ELEMENT rootElement (childElement)>
<!ATTLIST rootElement attribute CDATA #REQUIRED>
<!ENTITY entity "entity's content">
<!NOTATION notation SYSTEM "notation's data">

这里定义了根元素、子元素、属性和实体,以及一些引用的符号。

2.1.2 元素的层次结构

XML元素是XML文档的构建块,元素的层次结构通过嵌套来表示。每个元素由一个起始标签开始,后面可以包含文本、其他标签以及属性。元素以结束标签结束。例如:

<root>
    <child id="1">Child Content</child>
    <sibling>Another child</sibling>
</root>

在上述例子中, <root> 是根元素,包含两个子元素 <child> sibling> 。每个元素都拥有清晰的层次结构,使得数据的组织和处理变得直观。

2.2 XML的数据表达能力

2.2.1 属性和文本的使用

属性提供了有关元素的附加信息。在XML中,属性可以被视为元素的键值对。它们必须出现在元素的起始标签中,并且必须以单引号或双引号包围。例如:

<book id="bk101">
    <author>Gambardella, Matthew</author>
    <title>XML Developer's Guide</title>
</book>

在这个例子中, id book 元素的一个属性,为该元素提供了唯一标识。

文本内容直接位于元素的起始标签和结束标签之间。元素可以包含其他元素,属性,文本或这些的任意组合。文本内容应当包含在标签之间,如下所示:

<paragraph align="left">This is some text content.</paragraph>

2.2.2 CDATA区域与字符转义

CDATA区域用于告知XML解析器其中的文本不应该被解析为标记,通常用于包含需要被保留的字符,如 < > 等。CDATA区段由 <![CDATA[ 开始,由 ]]> 结束。例如:

<description><![CDATA[This is a <book> tag with <content>.]]></description>

如果文本中包含需要转义的特殊字符,可以使用字符实体的引用。例如,小于号 < 可以用 &lt; 来表示。这些转义字符保证了XML文档的有效性和可读性。

3. XML元素、属性和命名空间

3.1 XML元素和属性的设计

3.1.1 元素的嵌套和结构化

XML文档的核心由元素构成,元素的嵌套规则至关重要,它们为数据的组织和结构化提供了清晰的蓝图。一个XML元素由一个开始标签(start tag),一个结束标签(end tag)和两者之间的内容组成。例如:

<book>
    <title>Professional XML</title>
    <author>John Doe</author>
</book>

在上述示例中, <book> 是一个开始标签, </book> 是对应的结束标签。 <title> <author> 是嵌套在 <book> 元素内部的子元素。元素可以无限层级嵌套,但必须保证正确的嵌套顺序和层次结构。即每一个开始标签都必须有一个对应结束标签,并且按照开启的顺序闭合。

3.1.2 属性的作用与限制

属性提供了元素额外的信息,并且总是位于开始标签内。属性应被看作是元素的元数据,而不是内容。例如:

<book isbn="***">
    <title>Professional XML</title>
    <author>John Doe</author>
</book>

在这个例子中, isbn 是一个属性,它为 book 元素提供了附加的信息。XML文档中对属性的要求如下:

  • 每个元素的属性必须有唯一的名称。
  • 属性不能嵌套,它们不能包含子元素或属性。
  • 属性值必须被引号包围。

属性虽然为元素提供了灵活性,但过度使用会导致数据的难以维护和解析器的性能下降。因此,应谨慎使用属性,仅当需要为元素提供额外的元数据时采用。

3.2 命名空间的使用

3.2.1 命名空间的定义和作用

为了使XML文档中不同来源的元素和属性得以区分,并且避免命名冲突,引入了命名空间的概念。命名空间通过一个URI(统一资源标识符)来唯一标识,并且通常与前缀关联。

例如:

<books:books xmlns:books="***">
    <books:book>
        <books:title>Professional XML</books:title>
        <books:author>John Doe</books:author>
    </books:book>
</books:books>

在上述代码中, xmlns:books="***" 定义了一个前缀 books ,它与URI "***" 关联,表示所有使用 books 前缀的元素都属于这个命名空间。

命名空间的使用为XML文档带来了几个好处:

  • 允许在同一个文档中使用相同名称的元素,只要它们属于不同的命名空间。
  • 提高了XML文档的可读性和可维护性。
  • 通过URI的唯一性,可以轻松地识别和引用不同来源的数据。

3.2.2 命名空间与XML文档的整合

命名空间应当谨慎使用,并且需要与XML文档的结构紧密结合。它们不仅用于区分不同的元素集合,还能帮助开发者理解元素的来源和用途。

整合命名空间的步骤一般包括:

  1. 为XML文档中的不同元素集合定义不同的URI。
  2. 选择合适的前缀来代表这些URI。
  3. 在元素和属性上应用这些前缀,从而将它们绑定到对应的命名空间。

整合命名空间时,一些最佳实践包括:

  • 避免使用过长的URI,因为它们将频繁出现在文档中。
  • URI不必指向实际的资源,它仅用作标识符。
  • 确保使用前缀的前后一致性,便于理解。

命名空间的合理应用可以显著提升XML文档的结构化和灵活性,但同时也可能增加解析复杂性。因此,开发者需要在两者之间找到平衡点。

4. XML解析技术(DOM和SAX)

4.1 DOM解析模型

4.1.1 DOM解析器的工作原理

文档对象模型(Document Object Model, DOM)是一种以树形结构表示XML或HTML文档的接口。DOM解析器的工作原理是将XML文档转换成一系列节点和对象,这样可以方便地通过程序语言(如JavaScript, Java等)遍历和操作这个树形结构。

DOM解析器通常执行以下步骤来解析一个XML文档:

  1. 读取XML文件: DOM解析器会从头到尾读取XML文件,将文件内容转换成内部格式。
  2. 构建树形结构: 解析器创建一个树状结构,将XML文档的每个组成部分映射成树中的一个节点(如元素节点、属性节点、文本节点等)。
  3. 构建文档对象: 树形结构建立后,DOM解析器提供一个文档对象,应用程序可以通过操作这个对象访问和修改文档内容。

一个典型的DOM解析过程包括以下几个核心对象:

  • Document :代表整个XML文档。
  • Element :代表XML文档中的元素。
  • Attr :代表元素的属性。
  • Text :代表元素或属性中的文本内容。
  • Node :所有DOM对象的基类,提供访问树节点的方法和属性。

4.1.2 使用DOM进行数据操作

DOM解析提供了一种直观的方式来读取和更新XML文档。以下是一个使用DOM解析器进行数据操作的实例代码(使用Java语言):

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

public class SimpleDOM {
    public static void main(String[] args) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse("example.xml"); // 加载XML文件
        // 获取根节点
        Element root = document.getDocumentElement();
        // 创建一个新节点并添加到根节点下
        Element newElement = document.createElement("newElement");
        Text newText = document.createTextNode("This is a new text node");
        newElement.appendChild(newText);
        root.appendChild(newElement);
        // 输出修改后的XML
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        javax.xml.transform.Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        DOMSource source = new DOMSource(document);
        StreamResult result = new StreamResult(System.out);
        transformer.transform(source, result);
    }
}

这段代码首先读取一个名为 example.xml 的文件,然后创建一个新的元素节点 newElement ,并给它添加了一个文本节点。之后,将这个新元素添加到了文档的根节点下。最后,使用 Transformer 对象输出修改后的XML文档内容。

在这个过程中,可以进行任何你需要的读取和修改操作。DOM解析器提供了一个强大的、面向对象的API来操作XML文档中的数据,非常适合需要频繁访问XML文档中数据的应用程序。

4.2 SAX解析技术

4.2.1 SAX的工作机制和优势

简单APIXML(Simple API for XML,SAX)是一种基于事件的XML解析技术。与DOM不同,SAX不需要将整个XML文档加载到内存中,因此SAX在处理大型文件时具有优势。

SAX工作机制如下:

  1. 事件驱动: SAX解析器读取XML文件时,会触发一系列事件,例如开始元素、结束元素、文本内容等。
  2. 回调函数: 解析器在触发事件时,会调用与事件关联的回调函数。开发者需要在这些回调函数中编写处理逻辑。
  3. 逐行读取: 解析器逐行读取XML文档,处理完毕后即释放内存,因此对于大文件,内存占用相对较小。

使用SAX的优势主要体现在:

  • 内存效率: 由于是事件驱动模型,不需要在内存中存储整个文档的树结构,特别适合处理大型文档。
  • 处理速度快: 只需读取一次XML文档,不需要像DOM那样在内存中构建复杂的树结构。
  • 无需完整的XML文档: SAX可以在接收到文件的任何一部分时立即开始解析,这对于流式数据处理非常有用。

4.2.2 实现SAX事件处理

下面是一个使用Java实现SAX事件处理的基本示例:

import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

public class SimpleSAX extends DefaultHandler {
    public static void main(String[] args) throws Exception {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        parser.parse("example.xml", new SimpleSAX());
    }

    // 开始文档
    public void startDocument() throws SAXException {
        System.out.println("Start document");
    }

    // 开始元素
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        System.out.println("Start element :" + qName);
    }

    // 文本内容
    public void characters(char[] ch, int start, int length) throws SAXException {
        System.out.println("Characters: " + new String(ch, start, length));
    }

    // 结束元素
    public void endElement(String uri, String localName, String qName) throws SAXException {
        System.out.println("End element :" + qName);
    }

    // 结束文档
    public void endDocument() throws SAXException {
        System.out.println("End document");
    }
}

在这个SAX解析示例中,重写了 DefaultHandler 类中的几个方法,分别对应XML解析中的不同事件:

  • startDocument :当开始解析文档时触发。
  • startElement :当遇到元素的开始标签时触发。
  • characters :当读取到元素中的文本内容时触发。
  • endElement :当遇到元素的结束标签时触发。
  • endDocument :当解析文档结束时触发。

通过重写这些方法,可以灵活地处理XML文档中的数据,而无需将整个文档读入内存。这种方法特别适用于需要从大型XML文件中提取少量数据的场景。

表格、流程图和代码块补充说明

表格补充

对于SAX解析技术的讨论,我们可以创建一个表格来比较DOM和SAX的技术特点:

| 特性 | DOM解析 | SAX解析 | |------------------|--------------------------------|--------------------------------| | 解析方式 | 加载整个文档到内存,构建树状结构 | 逐行读取,基于事件的解析 | | 适合场景 | 需要频繁访问和修改文档结构的场景| 需要处理大型文件或流式数据的场景| | 内存占用 | 较高 | 较低 | | 编程复杂度 | 较低(但需要熟悉文档对象模型) | 较高(需要编写事件处理逻辑) | | 解析速度 | 较慢(构建树结构需要时间) | 较快 |

代码块补充

在讨论SAX解析技术时,我们用代码块展示了如何实现一个简单的SAX处理器。需要注意的是,SAX提供的是一种轻量级的处理方式,特别适合于只需要读取XML文件部分数据的场景。每种事件方法的实现都应该根据实际需求编写具体的处理逻辑,这样才能有效地从XML文档中提取所需信息。

流程图补充

我们可以通过mermaid格式的流程图来形象地表示SAX解析XML文件的过程:

graph LR
    A[开始解析XML文件] --> B[触发开始文档事件]
    B --> C[逐行读取XML]
    C --> D{触发事件}
    D --> |开始元素| E[处理元素开始]
    D --> |字符数据| F[处理文本内容]
    D --> |结束元素| G[处理元素结束]
    E --> H{是否到达文件末尾}
    F --> H
    G --> H
    H -->|是| I[触发结束文档事件]
    H -->|否| C
    I --> J[结束解析]

这个流程图描绘了SAX解析器在解析XML文件过程中,根据XML文档结构触发各种事件,并处理这些事件的过程。通过这种方式,SAX解析器能够以流的形式处理XML文件,同时在处理过程中只需要维持有限的状态信息,大大减少了内存的使用。

小结

通过本章节的介绍,我们可以看到,XML解析技术是处理XML数据的核心。DOM提供了一种直观、强大的方式来操作整个XML文档,适合结构复杂、需要频繁操作的场景。而SAX则提供了一种轻量级、事件驱动的方式处理XML,尤其适合于大型文件和流式数据处理。根据不同的应用场景选择合适的解析技术,对于开发者来说至关重要。

5. XML应用实例(XSLT和XPath)

5.1 XSLT样式表的应用

5.1.1 XSLT的基本概念和结构

XSLT(Extensible Stylesheet Language Transformations)是一种用于转换XML文档的语言。它允许开发者定义如何将一个XML文档转换为另一个文档,这可以是HTML、XML或任何其他文本格式。XSLT使用自己的XML语法,通过定义规则来处理XML元素,从而实现格式的转换。

一个基本的XSLT样式表包含以下三个主要部分: - <xsl:stylesheet> <xsl:transform> 根元素。 - 模板(Templates)和匹配模式(Matching patterns)。 - 输出指令(Output instructions)。

5.1.2 创建XSLT样式表进行数据转换

下面我们将通过一个简单的例子来展示如何使用XSLT样式表转换XML文档。

首先,假设我们有如下的XML文档( books.xml ):

<library>
    <book>
        <title>XML Fundamentals</title>
        <author>John Doe</author>
        <price>29.99</price>
    </book>
    <book>
        <title>Advanced XML</title>
        <author>Jane Doe</author>
        <price>39.99</price>
    </book>
</library>

然后,我们创建一个XSLT样式表( books.xsl )来转换上述XML文档:

<xsl:stylesheet version="1.0" xmlns:xsl="***">
    <xsl:output method="html" encoding="UTF-8"/>
    <xsl:template match="/">
        <html>
            <head><title>Library Catalog</title></head>
            <body>
                <h1>Library Catalog</h1>
                <table border="1">
                    <tr bgcolor="#9acd32">
                        <th>Title</th>
                        <th>Author</th>
                        <th>Price</th>
                    </tr>
                    <xsl:for-each select="library/book">
                    <tr>
                        <td><xsl:value-of select="title"/></td>
                        <td><xsl:value-of select="author"/></td>
                        <td><xsl:value-of select="price"/></td>
                    </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

在这个XSLT样式表中,我们定义了如何将XML文档中的每个 <book> 元素转换成HTML表格中的行。注意 <xsl:for-each> 用于迭代 <library> 下的每个 <book> 元素, <xsl:value-of> 则用于提取特定节点的文本内容。

执行这个XSLT样式表之后,将生成一个包含书籍信息的HTML表格。

5.2 XPath表达式的应用

5.2.1 XPath语法基础

XPath是一种用于在XML文档中查找信息的语言。它允许开发者通过路径表达式来选择XML文档中的节点或节点集。XPath使用一个简短的记法来描述XML文档中的位置路径,使开发者能够快速定位到需要的数据。

基本XPath表达式包括以下类型: - 节点选择器,如 / 代表根节点, // 代表任意位置的节点。 - 节点名称,用于选择特定名称的节点,如 /book/title 。 - 属性选择器,如 [@price > 20] 用于选择具有特定属性值的节点。 - 通配符,如 * 代表任意元素, @* 代表任意属性。

5.2.2 XPath在XSLT中的应用实例

在前面创建的XSLT样式表中,我们实际上已经使用了XPath来提取每个书籍节点的 <title> <author> <price> 信息。接下来,我们通过一个新例子来进一步了解XPath的用法。

假设我们需要找到所有价格超过30元的书籍,可以在XSLT样式表中使用如下XPath表达式:

<xsl:template match="library">
    <h2>Books with price greater than 30</h2>
    <ul>
        <xsl:for-each select="book[price > 30]">
        <li><xsl:value-of select="title"/> by <xsl:value-of select="author"/></li>
        </xsl:for-each>
    </ul>
</xsl:template>

在这里, book[price > 30] 是一个XPath表达式,它选择所有 <book> 元素,其子元素 <price> 的值大于30。然后,我们使用 <xsl:for-each> 遍历这些书籍,并使用 <xsl:value-of> 显示它们的 <title> <author>

通过这种结合XSLT和XPath的方法,可以灵活地实现复杂的数据转换和提取任务。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:《XML实用技术第二版:从示例到实践》是为具备HTML和JavaScript基础的读者编写,旨在通过示例教学提升XML应用能力。本书详细介绍了XML语言在数据交换、配置文件和文档结构化中的作用,并解释了XML的设计目标、语法结构、命名空间以及元素、属性和文本内容的组成。此外,书中还涵盖了XML的两种主要解析方法DOM和SAX,以及与XSLT和XPath的集成使用,揭示了如何通过XSD进行数据验证。读者将学习创建XML文档、解析XML数据、转换XML格式以及XML在实际开发中的应用。本书内容结合理论和实践,是提升XML相关技能的宝贵资源。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值