了解 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. spring Security 得到认证用户名的方法

    @Service("userService")public class UserServiceImpl implements UserService { @Overridepubl ...

  2. PAT 1139 First Contact[难][模拟]

    1139 First Contact(30 分) Unlike in nowadays, the way that boys and girls expressing their feelings o ...

  3. C++ vector错误(1)

    在用C++的vector的时候,要保证访问的下标不能超过vector的size.否则出现msvcp60.dll 访问禁止.

  4. 1.1 、Django 后台

    Django 后台 与后台相关文件:每个app中的 admin.py 文件与后台相关. 一,新建一个 名称为 HelloDjango 的项目 django-admin.py startproject ...

  5. (13)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第一部分

    引言 程序截图: 本教程将会教大家如何使用Cocos2d-x来做一个基于tile地图的游戏,当然还有Tiled地图编辑器.(我们小时候玩的小霸王小学机里面的游戏,大部分都是基于tile地图的游戏,如坦 ...

  6. cocos-lua基础学习(九)spite类学习笔记

    创建精灵 ,) ) layer:addChild( sprite ) ) layer:addChild(BatchNode, , kTagSpriteBatchNode) ,) ) layer:add ...

  7. 什么是T-SQL

    T-SQL T-SQL 即 Transact-SQL,是 SQL 在 Microsoft SQL Server 上的增强版,它是用来让应用程序与 SQL Server 沟通的主要语言.T-SQL 提供 ...

  8. poj1942 Paths on a Grid(无mod大组合数)

    poj1942 Paths on a Grid 题意:给定一个长m高n$(n,m \in unsigned 32-bit)$的矩形,问有几种走法.$n=m=0$时终止. 显然的$C(m+n,n)$ 但 ...

  9. 配置zbar识别二维码(转载)

    原文地址:http://blog.csdn.net/dcrmg/article/details/52108258  二维码解码器Zbar+VS2012开发环境配置 Zbar条码解码器是一个开源的二维码 ...

  10. UVa 1664 Conquer a New Region(并查集)

    https://vjudge.net/problem/UVA-1664 题意: n个城市形成一棵树,每条边有权值C(i,j).任意两个点的容量S(i,j)定义为i与j唯一通路上容量的最小值.找一个点, ...