转:XML 中的空白字符须知:xml:space
了解 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的更多相关文章
- JAVA web.xml中引用多个XML
web.xml里加<context-param><param-name>contextConfigLocation</param-name><param-va ...
- CSS控制XML与通过js解析xml然后通过html显示xml中的数据
使用CSS控制XML的显示 book.css bookname{ display:block;color:Red} author{ display:block;font-style:italic} p ...
- xml 中转意字符&\/使用方法
所有 XML 元素都须有关闭标签 在 HTML,经常会看到没有关闭标签的元素: <p>This is a paragraph <p>This is another paragr ...
- 如何在web.xml文件中引入其他的xml文件(拆分web.xml)
转载自:http://www.blogjava.net/jiangjf/archive/2009/04/09/264685.html 最近在做一个Servlet+javaBean的项目,服务器用的是t ...
- SpringMVC(十六):如何使用编程方式替代/WEB-INF/web.xml中的配置信息
在构建springmvc+mybatis项目时,更常用的方式是采用web.xml来配置,而且一般情况下会在web.xml中使用ContextLoaderListener加载applicationCon ...
- java:struts2.3框架1(struts2快速配置,各文件之间的关系,基础代码简化版,XML中的通配符)
1.struts2快速配置: A.到http://struts.apache.org下载struts2开发包struts-2.3.32-all.zip B.新建web项目并添加struts2依赖的ja ...
- 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 ...
- Tomcat web.xml中定义了文件扩展名到MIME类型的对应关系
Tomcat在返回静态资源时,会根据资源文件的扩展名产生对应的content-type头(也即MIME类型)添加到response header中. 在Tomcat的web.xml规定了扩展名及相应M ...
- DOM【介绍、HTML中的DOM、XML中的DOM】
什么是DOM? DOM(Document Object Model)文档对象模型,是语言和平台的中立接口. 允许程序和脚本动态地访问和更新文档的内容. 为什么要使用DOM? Dom技术使得用户页面可以 ...
随机推荐
- Atom+Nuclide(Windows)开发ReactNative
1 安装Atom,Nucilde 首先需要到官网下载Atom: 然后安装Nuclide, 重新打开Atom,会看到Nucilde的界面且菜单项会多出一个Nucilde 2 创建ReactNative ...
- EasyUI Draggable 可拖动
通过 $.fn.draggable.defaults 重写默认的 defaults. 用法 通过标记创建可拖动(draggable)元素. <div id="dd" clas ...
- Flask系列之蓝图中使用动态URL前缀
让我们先来看一个简单的例子,假设有下面这样一个蓝图(是关于用户主页的): from flask import Blueprint, render_template profile = Blueprin ...
- OpenStack功能简介
为什要用云? 一.简单的说就是对资源更加合理的分配,使用,比如硬件的数量,带宽等等这些,因为你不能机器买来不需要了再卖掉(当然也可以),带宽跟机房签合同得来一年的,中间不够了也不能加,超了也不退钱 二 ...
- KL与JS散度学习[转载]
转自:https://www.jianshu.com/p/43318a3dc715?from=timeline&isappinstalled=0 https://blog.csdn.net/e ...
- php array_map array_filter sort
array_map — Applies the callback to the elements of the given arrays (处理映射) array_filter — Filters e ...
- ruby md5 sha1 base64加密
#md5加密 require 'md5' puts MD5.hexdigest('admin') #sha1加密 require 'digest/sha1' puts Digest::SHA1.hex ...
- Codeforces Round #513 by Barcelona Bootcamp
A. Phone Numbers 签. #include <bits/stdc++.h> using namespace std; #define N 110 char s[N]; ], ...
- ng-深度学习-课程笔记-9: 机器学习策略1(Week1)
1 为什么要应用机器学习策略( Why is machine learning strategy ) 当你想优化一个问题的时候,通常可以有很多尝试(比如收集更多数据,增加迭代次数,改用adam,改变网 ...
- 20144303石宇森《网络对抗》逆向及Bof基础
20144303石宇森<网络对抗>逆向及Bof基础 一.实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回 ...