了解 XML 空白字符的概念并掌握如何避免与之相关的问题的技巧。

2006 年 4 月发布

很多时候,您可能都没注意到,在 XML 中所做的更改影响着您访问 XML 文档中数据的方式。例如:

<Author><FirstName>John</FirstName>
<LastName>Smith</LastName></Author>

完全不同于

<Author>
<FirstName>John</FirstName>
<LastName>Smith</LastName> </Author>

以下是一个完整的示例(请参阅示例代码中的示例 1):假设您希望使用 DOM API 获取 <Author> 的第一个子元素,如下所示:

XMLDocument doc = parser.getDocument();
Element elem = doc.getDocumentElement();
Node node = elem.getFirstChild();

利用 Oracle XDK DOM 分析器的默认设置,第一个文档返回 <FirstName> 的同时,第二个文档返回一个为空白字符节点的文本节点。

同样,有时 XSLT 转换不会生成您预期的结果。(请参阅示例 2。)XML 文档需要使用 XSLT 进行转换。XSL 样式表使用 position() 函数来为 <Chapter> 和 <Section> 元素创建排序信息:

<?xml version="1.0"?>
<Book>
<Chapter>
<Section/>
<Section/>
<Section/>
</Chapter>
<Chapter>
<Section/>
<Section/>
<Section/>
</Chapter>
</Book>

然而,以下 XSL 样式表:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:attribute name="Position">
<xsl:value-of select="position()"/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

并不会按期望运行,它将产生以下结果:

<?xml version = '1.0' encoding = 'UTF-8'?>
<Book Position="1">
<Chapter Position="2">
<Section Position="2"/>
<Section Position="4"/>
<Section Position="6"/>
</Chapter>
<Chapter Position="4">
<Section Position="2"/>
<Section Position="4"/>
<Section Position="6"/>
</Chapter>
</Book>

位置不正确是由空白字符造成的。如果在 XSLT 转换中调用 position() 函数删除之前使用以下样式表删除空白字符:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

将生成期望的结果:

<?xml version = '1.0' encoding = 'UTF-8'?>
<Book Position="1">
<Chapter Position="1">
<Section Position="1"/>
<Section Position="2"/>
<Section Position="3"/>
</Chapter>
<Chapter Position="2">
<Section Position="1"/>
<Section Position="2"/>
<Section Position="3"/>
</Chapter>
</Book>

对于此例,如果不希望删去所有 XML 元素的空白字符,可使用 <xsl:strip-space element="Book,Chapter, Section"> 代替。

以下部分将介绍 XML 空白字符的概念以及避免此类问题的技巧。

什么是 XML 空白字符?

XML 将以下四种字符归为空白字符:回车符(\r 或 ch(13))、换行符(\n 或 ch(10))、制表符 (\t) 以及空格 (' ')。在 XML 文档中,空白字符分为两类:

  • 有意义空白字符 是文档内容的一部分,应予以保留。
  • 无意义空白字符 在编辑 XML 文档时使用,以增加可读性。这些空白字符一般在文档交付时不予保留。

通常,若没有 DTD (文档类型定义(Document Type Definition)是一套为了进行程序间的数据交换而建立的关于标记符的语法规则)或 XML 模式定义,所有空白字符都是有意义空白字符,应当保留。然而,如果有 DTD 或 XML 模式定义,则只有以下内容中的空白字符有意义:

<sig>
------------------
John Smith
Product Manager
Example.com
--------------------
</sig>

XML 处理器如何处理 XML 空白字符

XML 标准详细说明了 XML 处理器应如何处理空白字符。

XML 分析:XML 规范提供了一个内置属性 xml:space 来告知 XML 分析器其是否应忽略空白字符。该属性由其根元素的子元素来继承。声明时,必须将其指定为枚举类型,其可能的值只能是“ default”和“ preserve”。如果指定为“ preserve”,则所定义元素内的空白字符必须保留。

根据 W3C XML 规范,默认情况下,Oracle XML 开发人员工具包 (XDK) XML 分析器将保留所有空白字符。因此, xml:space =“ default”或 xml:space =“ preserve ”将具有相同的作用:保留空白字符。若要避免保留空白字符,需要按如下所示设置 Oracle XDK 分析器:

XDK DOM Parser:

DOMParser parser = new DOMParser();
parser.setPreserveWhitespace(false);

SAX Parser:

SAXParser parser = new SAXParser();
parser.setPreserveWhitespace(false);

XSLT 转换。W3C XSLT 规范提供了两个元素(即 xsl:strip-space 和 xsl:preserve-spacea€”)来处理空白字符。 xsl:strip-space 指定了应删除空白字符文本节点(即文本节点完全由空白字符组成)的 XML 元素。请注意, xsl:strip-space 只有影响纯空白字符的节点。 xsl:strip-space 可以列为一组由空白字符或使用通配符(例如 *)隔开的元素。 xsl:preserve-space 具有类似的语法,但执行的结果却与 xsl:strip-space 正好相反。

以下示例(请参阅示例 3)应用了一个复制源文档的 XSL 样式表,但删去了空白字符文本节点:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/> <xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

对于如下所示的 XML 文档:

<rootElement>
<childElement test="true">
Value
</childElement>This is the test
<childElement test="true" xml:space="preserve">
Value
</childElement>
<childElement xml:space="preserve">
</childElement>
<childElement>
</childElement>
</rootElement>

XSLT 转换将生成以下结果:

<rootElement><childElement test="true">
Value
</childElement>This is the test
<childElement test="true" xml:space="preserve">
Value
</childElement><childElement xml:space="preserve">
</childElement><childElement/></rootElement>

您可能注意到,如果 XML 元素中的 xml:space=" preserved,则不会删去空白字符。这种行为基于 XSLT 规范,该规范定义了保留空白字符的条件:

文本节点的父元素具有的 xml:space 属性值为 preserve,并且没有更近的父元素具有带有默认值的 xml:space。

XSLT 还提供 normalize-space() 函数,将包含多个空白字符的字符串转换为一个空白字符,从作为参数传递给它的字符串删除所有前导空白字符和尾随空白字符。

DOM 序列化。序列化 XML 文档时,输出缩进将添加无意义空白字符。默认情况下,Oracle XDK DOM 分析器将以缩进格式打印 XML DOM 文档。

要避免缩进, 在 XDK 9i 中,可将 oracle.xml.parser.v2.XMLPrintDriver 类划分为子类,如下所示(请参阅示例 4):

import oracle.xml.parser.v2.XMLPrintDriver;
import oracle.xml.parser.v2.XMLOutputStream;
class MyXMLPrintDriver extends XMLPrintDriver
{
public MyXMLPrintDriver(java.io.OutputStream A)
{
super(A);
out.setOutputStyle(XMLOutputStream.COMPACT);
}
}

在 Oracle XDK 10g 中,新增了一个函数 oracle.xml.parser.v2.XMLPrintDriver.setFormatPrettyPrint(),可用于避免执行子类划分操作。使用 Oracle XDK 10g,您可以打印不带缩进的 XML DOM 文档,如下所示(请参阅示例 5):

XMLPrintDriver myprint = new XMLPrintDriver(System.out);
myprint.setFormatPrettyPrint(false);
Xml_doc.print(myprint);

结论

现在,利用这些基本知识,您可以成功避免由 XML 文档中的空白字符引发的问题。

原链接:http://www.oracle.com/technetwork/cn/topics/xml/wang-whitespace-095149-zhs.html

转:XML 中的空白字符须知:xml:space的更多相关文章

  1. JAVA web.xml中引用多个XML

    web.xml里加<context-param><param-name>contextConfigLocation</param-name><param-va ...

  2. CSS控制XML与通过js解析xml然后通过html显示xml中的数据

    使用CSS控制XML的显示 book.css bookname{ display:block;color:Red} author{ display:block;font-style:italic} p ...

  3. xml 中转意字符&\/使用方法

    所有 XML 元素都须有关闭标签 在 HTML,经常会看到没有关闭标签的元素: <p>This is a paragraph <p>This is another paragr ...

  4. 如何在web.xml文件中引入其他的xml文件(拆分web.xml)

    转载自:http://www.blogjava.net/jiangjf/archive/2009/04/09/264685.html 最近在做一个Servlet+javaBean的项目,服务器用的是t ...

  5. SpringMVC(十六):如何使用编程方式替代/WEB-INF/web.xml中的配置信息

    在构建springmvc+mybatis项目时,更常用的方式是采用web.xml来配置,而且一般情况下会在web.xml中使用ContextLoaderListener加载applicationCon ...

  6. java:struts2.3框架1(struts2快速配置,各文件之间的关系,基础代码简化版,XML中的通配符)

    1.struts2快速配置: A.到http://struts.apache.org下载struts2开发包struts-2.3.32-all.zip B.新建web项目并添加struts2依赖的ja ...

  7. xml语法、DTD约束xml、Schema约束xml、DOM解析xml

    今日大纲 1.什么是xml.xml的作用 2.xml的语法 3.DTD约束xml 4.Schema约束xml 5.DOM解析xml 1.什么是xml.xml的作用 1.1.xml介绍 在前面学习的ht ...

  8. Tomcat web.xml中定义了文件扩展名到MIME类型的对应关系

    Tomcat在返回静态资源时,会根据资源文件的扩展名产生对应的content-type头(也即MIME类型)添加到response header中. 在Tomcat的web.xml规定了扩展名及相应M ...

  9. DOM【介绍、HTML中的DOM、XML中的DOM】

    什么是DOM? DOM(Document Object Model)文档对象模型,是语言和平台的中立接口. 允许程序和脚本动态地访问和更新文档的内容. 为什么要使用DOM? Dom技术使得用户页面可以 ...

随机推荐

  1. linux/Mac使用du查看目录占用的磁盘大小

    [1]du命令用来查看目录或文件所占用磁盘空间的大小.常用选项组合为: du -sh [2]若要查看一个目录下每个文件和文件夹的磁盘占用空间,使用如下命令: du -ah --max-depth=1 ...

  2. Mybatis入门和简单Demo

    一.Mybatis的诞生 回顾下传统的数据库开发,JDBC和Hibernate是使用最普遍的技术,但这两种ORM框架都存在一定的局限性: JDBC:最原生的技术,简单易学,执行速度快,效率高,适合大数 ...

  3. 单台DNS服务器搭建(BIND)

    一.理论层面 1. DNS的出现及演化 网络出现的早期是使用IP地址通讯的,那是就几台主机通讯.但是随着接入网络主机的增多,这种数字标识的地址非常不便于记忆,UNIX上就出现了建立一个叫做hosts的 ...

  4. Common Knowledge

    2014-08-23 11:01:11 -6:四面体 (1)内切球半径:r = 3V / (S1+S2+S3+S4) (2)体积:将四点组成三个向量AB,AC,AD,向量的混合积就是它们组成的平行六面 ...

  5. 查看本地mysql安装路径

  6. hdu3037 Saving Beans(Lucas定理)

    hdu3037 Saving Beans 题意:n个不同的盒子,每个盒子里放一些球(可不放),总球数<=m,求方案数. $1<=n,m<=1e9,1<p<1e5,p∈pr ...

  7. 微信小程序:全局配置app.json

    微信小程序:全局配置app.json 一.全局配置app.json app.json文件用来对微信小程序进行全局配置,决定页面文件的路径.窗口表现.设置网络超时时间.设置多 tab 等. 以下是一个包 ...

  8. #ZLYD团队第二周项目总结

    ZLYD团队第二周项目总结 项目进展 确定项目内容.目标.实现计划 首先确定游戏界面的游戏区域中墙的位置,绘制其图形,并通过其中的方法,返回墙壁的位置等属性. 根据豆子的位置,绘制其图形. 初始化吃豆 ...

  9. libcurl开源库在Win7 + VS2012环境下编译、配置详解 以及下载文件并显示下载进度 demo(转载)

    转载:http://blog.csdn.net/fengshuiyue/article/details/39530093(基本教程) 转载:https://my.oschina.net/u/14207 ...

  10. linux突然断电重启,配置文件丢失/程序无法打开/文件损坏

    电脑突然断电,重新开机后发现有的程序无法正常启动,原因是配置文件损坏了.感觉奇怪,为什么在硬盘里的文件会内容丢失? 1.可能:写数据的过程被中断,只完成了一部分.可能会出现乱码(因为只写了几个字节,不 ...