了解 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. POJ1523:SPF(无向连通图求割点)

    题目:http://poj.org/problem?id=1523 题目解析: 注意题目输入输入,防止PE,题目就是求割点,并问割点将这个连通图分成了几个子图,算是模版题吧. #include < ...

  2. HTML5游戏开发系列教程9(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-9/ 今天我们将继续使用canvas来进行HTML5游戏开发系列的 ...

  3. 32Sql数据库的插入

    上一节讲了数据库的连接,本例直接将数据库的插入操作,重点还是QSqlQuery类 QSqlQuery query; //新建二维表 query.exec("CREATE TABLE stud ...

  4. Java 动态代理是基于什么原理

    动态代理 ①动态代理概念理解 动态代理是一种方便运行时动态构建代理.动态处理代理方法调用的机制,很多场景都利用类似机制做到的,比如用来包装RPC调用.面向切面的变成(AOP) 实现动态代理的方式很多, ...

  5. POI之Excel导入

    1,maven配置 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-oox ...

  6. 20145122《Java程序设计》第一周学习总结

    这周的JAVA学习开始了. 首先我了解JVM.JRE与JDK的区别与联系.JDK : (Java开发工具包).JDK是整个Java的核心,包括了Java运行环境JRE.Java工具和Java基础类库等 ...

  7. Java实现:数据结构之排序

    Java实现:数据结构之排序 0.概述 形式化定义:假设有n个记录的序列(待排序列)为{ R1, R2 , -, Rn },其相应的关键字序列为 { K1, K2, -, Kn }.找到{1,2, - ...

  8. 线程访问ui,使用委托方式

    转:https://www.cnblogs.com/muyoucai/p/6257213.html Control类提供了一个Invoke方法来给子线程访问主线程的控件,它的原型是酱紫的: objec ...

  9. TortoiseGit 访问https远程仓库,上报SSL证书错误解决方法

    报错 在使用TortoiseGit时,clone自己搭建的gitlab报如错SSL certificate problem: self signed certificate 原因:自行搭建的gitla ...

  10. 寻找List之和的最近素数

    Task : Given a List [] of n integers , find minimum mumber to be inserted in a list, so that sum of ...