XML 解析
创新互联技术团队十载来致力于为客户提供成都网站建设、成都做网站、品牌网站设计、成都全网营销推广、搜索引擎SEO优化等服务。经过多年发展,公司拥有经验丰富的技术团队,先后服务、推广了上千多家网站,包括各类中小企业、企事单位、高校等机构单位。
XML 解析是将 XML 数据从其序列化字符串格式转换为分层格式的过程。
可以让 DB2® 数据库管理器隐式执行解析,也可以显式执行 XML 解析。
在下列情况下进行隐式 XML 解析:
使用类型为 XML 的主变量或使用类型为 XML 的参数标记将数据传递至数据库服务器时
数据库服务器在绑定主变量或参数标记的值以便在语句处理期间使用时进行解析
在这种情况下,必须使用隐式解析。
在 INSERT、UPDATE、DELETE 或 MERGE 语句中将字符串数据类型(character、graphic 或 binary)的主变量、参数标记或 SQL 表达式指定给 XML 列时。当 SQL 编译器隐式将 XMLPARSE 函数添加至该语句时进行解析。
对输入 XML 数据调用 XMLPARSE 函数时,执行显式 XML 解析。可以在接受 XML 数据类型的任何上下文中使用 XMLPARSE 的结果。例如,可以将结果指定给 XML 列或将它用作类型为 XML 的存储过程参数。
XMLPARSE 函数采用非 XML、字符或二进制数据类型作为输入。对于嵌入式动态 SQL 应用程序,需要将表示 XMLPARSE 的输入文档的参数标记强制类型转换为相应的数据类型。例如:
INSERT INTO MyCustomer (Cid, Info)
VALUES (?, xmlparse(document cast(? as clob(1k)) preserve whitespace))
对于静态嵌入式 SQL 应用程序,不能将 XMLPARSE 函数的主变量自变量声明为 XML 类型(XML AS BLOB、XML AS CLOB 或 XML AS DBCLOB 类型)。
XML 解析和空格处理
在隐式或显式 XML 解析期间,将数据存储在数据库中时,可以控制是保留还是去掉边界空格字符。
根据 XML 标准,空格是文档中用于提高可读性的间隔字符(U+0020)、回车符(U+000D)、换行符(U+000A)或制表符(U+0009)。当任何这些字符作为文本字符串的一部分出现时,不将它们视为空格。
边界空格是出现在元素之间的空格字符。例如,在以下文档中,a 与 b 以及 /b 与 /a 之间的空格是边界空格。
a b and between /b /a
通过显式调用 XMLPARSE,可以使用 STRIP WHITESPACE 或 PRESERVE WHITESPACE 选项来控制是否保留边界空格。缺省行为是去掉边界空格。
通过隐式 XML 解析:
如果输入数据类型不是 XML 类型或未强制类型转换为 XML 数据类型,则 DB2 数据库管理器总是去掉空格。
如果输入数据类型是 XML 数据类型,则可以使用 CURRENT IMPLICIT XMLPARSE OPTION 专用寄存器来控制是否保留边界空格。可以将此专用寄存器设置为 STRIP WHITESPACE 或 PRESERVE WHITESPACE。缺省行为是去掉边界空格。
如果使用 XML 验证,则 DB2 数据库管理器将忽略 CURRENT IMPLICIT XMLPARSE OPTION 专用寄存器,并只使用验证规则来确定下列示例中是去掉还是保留空格:
xmlvalidate(? ACCORDING TO XMLSCHEMA ID schemaname)
xmlvalidate(?)
xmlvalidate(:hvxml ACCORDING TO XMLSCHEMA ID schemaname)
xmlvalidate(:hvxml)
xmlvalidate(cast(? as xml) ACCORDING TO XMLSCHEMA ID schemaname)
xmlvalidate(cast(? as xml))
在这些示例中,? 表示 XML 数据,而 :hvxml 是 XML 主变量。
有关 XML 验证如何影响空格处理方式的信息,请参阅 XML 验证。
XML 标准指定 xml:space 属性,它用于控制是去掉还是保留 XML 数据中的空格。xml:space 属性覆盖任何空格设置以进行隐式或显式 XML 解析。
例如,在以下文档中,无论 XML 解析选项如何,总是保留正好在 b 前后的空格,因为这些空格位于具有属性 xml:space="preserve" 的节点内:
a xml:space="preserve" b cc/cb /b/a
但是,在以下文档中,可以用 XML 解析选项控制正好在 b 前后的空格,因为这些空格位于具有属性 xml:space="default" 的节点内:
a xml:space="default" b cc/cb /b/a
XML 解析和 DTD
如果输入数据包含内部文档类型声明(DTD)或引用外部 DTD,则 XML 解析过程还会检查这些 DTD 的语法。此外,解析过程还:
应用内部和外部 DTD 定义的缺省值
扩展实体引用和参数实体
示例:文件 c8.xml 包含以下文档:
customerinfo xml:space="preserve" xmlns="" Cid='1008'
nameKathy Smith/name
addr country='Canada'
street14 Rosewood/street
cityToronto/city
prov-stateOntario/prov-state
pcode-zipM6W 1E6/pcode-zip
/addr
phone type='work'416-555-3333/phone
/customerinfo
在 JDBC 应用程序中,从文件中读取 XML 文档,并将数据插入到表 MyCustomer(它是样本 Customer 表的副本)的 XML 列 Info 中。让 DB2 数据库服务器执行隐式 XML 解析操作。
PreparedStatement insertStmt = null;
String sqls = null;
int cid = 1008;
sqls = "INSERT INTO MyCustomer (Cid, Info) VALUES (?, ?)";
insertStmt = conn.prepareStatement(sqls);
insertStmt.setInt(1, cid);
File file = new File("c8.xml");
insertStmt.setBinaryStream(2, new FileInputStream(file), (int)file.length());
insertStmt.executeUpdate();
未指定空格处理方式,因此采用缺省行为:去掉空格。但是,文档包含 xml:space="preserve" 属性,因此保留空格。这表示将保留文档中元素之间的回车符、换行符和空格。
如果检索存储的数据,则内容看起来如下所示:
customerinfo xml:space="preserve" xmlns="" Cid='1008'
nameKathy Smith/name
addr country='Canada'
street14 Rosewood/street
cityToronto/city
prov-stateOntario/prov-state
pcode-zipM6W 1E6/pcode-zip
/addr
phone type='work'416-555-3333/phone
/customerinfo
示例:假定以下文档位于 BLOB 主变量 blob_hostvar 中。
customerinfo xml:space="default" xmlns="" Cid='1009'
nameKathy Smith/name
addr country='Canada'
street15 Rosewood/street
cityToronto/city
prov-stateOntario/prov-state
pcode-zipM6W 1E6/pcode-zip
/addr
phone type='work'416-555-4444/phone
/customerinfo
在静态嵌入式 C 应用程序中,将主变量中的文档插入到表 MyCustomer 的 XML 列 Info 中。该主变量不是 XML 类型,因此需要显式执行 XMLPARSE。指定 STRIP WHITESPACE 以除去任何边界空格。
EXEC SQL BEGIN DECLARE SECTION;
SQL TYPE BLOB (10K) blob_hostvar;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL INSERT INTO MyCustomer (Cid, Info)
VALUES (1009,
XMLPARSE(DOCUMENT :blob_hostvar STRIP WHITESPACE));
文档包含 xml:space="default" 属性,因此指定了 STRIP WHITESPACE 的 XMLPARSE 将控制空格处理方式。这表示将除去文档中元素之间的回车符、换行符和空格。
如果检索存储的数据,则您将看到具有以下内容的单个行:
customerinfo xml:space="default" xmlns="" Cid='1009'
nameKathy Smith/nameaddr country='Canada'street15 Rosewood/street
cityToronto/cityprov-stateOntario/prov-statepcode-zipM6W 1E6/pcode-zip
/addrphone type='work'416-555-4444/phone/customerinfo
示例:在 C 语言应用程序中,主变量 clob_hostvar 包含以下文档,该文档包含内部 DTD:
!DOCTYPE prod [!ELEMENT description (name,details,price,weight)
!ELEMENT name (#PCDATA)
!ELEMENT details (#PCDATA)
!ELEMENT price (#PCDATA)
!ELEMENT weight (#PCDATA)
!ENTITY desc "Anvil"
]
product xmlns="" pid=''110-100-01''
description
namedesc;/name
detailsVery heavy/details
price 9.99 /price
weight1 kg/weight
/description
/product'
将数据插入到表 MyProduct 中,它是样本 Product 表的副本:
EXEC SQL BEGIN DECLARE SECTION;
SQL TYPE CLOB (10K) clob_hostvar;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL insert into
Product ( pid, name, Price, PromoPrice, PromoStart, PromoEnd, description )
values ( '110-100-01','Anvil', 9.99, 7.99, '11-02-2004','12-02-2004',
XMLPARSE ( DOCUMENT :clob_hostvar STRIP WHITESPACE ));
XMLPARSE 指定去掉空格,因此将除去文档内的边界空格。此外,在数据库服务器执行 XMLPARSE 时,它将实体引用 desc; 替换为它的值。
如果检索存储的数据,则您将看到具有以下内容的单个行:
product xmlns="" pid="110-100-01"descriptionnameAnvil
/namedetailsVery heavy/detailsprice 9.99 /price
weight1 kg/weight/description/product
XML(eXtensible Markup Language)即可扩展标记语言,它与HTML一样,都是处于SGML,标准通用语言。Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。
XML与Access,Oracle和SQL Server等数据库不同,数据库提供了更强有力的数据存储和分析能力,例如:数据索引、排序、查找、相关一致性等,XML仅仅是展示数据。事实上XML与其他数据表现形式最大的不同是:他极其简单。这是一个看上去有点琐细的优点,但正是这点使XML与众不同。
XML的简单使其易于在任何应用程序中读写数据,这使XML很快成为数据交换的唯一公共语言,虽然不同的应用软件也支持其它的数据交换格式,但不久之后他们都将支持XML,那就意味着程序可以更容易的与Windows、Mac OS, Linux以及其他平台下产生的信息结合,然后可以很容易加载XML数据到程序中并分析他,并以XML格式输出结果。
XML的前身是SGML(The Standard Generalized Markup Language),是自IBM从60年代就开始发展的GML(Generalized Markup Language)
同HTML一样, XML (可扩展标识语言)是通用标识语言标准(SGML)的一个子集,它是描述网络上的数据内容和结构的标准。尽管如此,XML不象HTML,HTML仅仅提供了在页面上显示信息的通用方法(没有上下文相关和动态功能) ,XML则对数据赋予上下文相关功能,它继承了SGML的大部分功能,却使用了不太复杂的技术。.
为了使得SGML显得用户友好,XML重新定义了SGML的一些内部值和参数,去掉了大量的很少用到的功能,这些繁杂的功能使得SGML在设计网站时显得复杂化。XML保留了SGML的结构化功能,这样就使得网站设计者可以定义自己的文档类型,XML同时也推出一种新型文档类型,使得开发者也可以不必定义文档类型。
因为XML是W3C制定的,XML的标准化工作由W3C的XML工作组负责,该小组成员由来自各个地方和行业的专家组成,他们通过email交流对XML标准的意见,并提出自己的看法 ()。因为XML 是个公共格式, (它不专属于任何一家公司),你不必担心XML技术会成为少数公司的盈利工具,XML不是一个依附于特定浏览器的语言
XML(可扩展标记语言)是从称为SGML(标准通用标记语言)的更加古老的语言派生出来的。SGML的主要目的是定义使用标签来表示数据的标记语言的语法。
标签由包围在一个小于号()和一个大于号()之间的文本组成,例如tag。起始标签(start tag)表示一个特定区域的开始,例如start;结束标签(end tag)定义了一个区域的结束,除了在小于号之后紧跟着一个斜线(/)外,和起始标签基本一样,例如/end。SGML还定义了标签的特性(attribute),它们是定义在小于号和大于号之间的值,例如img src="picture.jpg"中的src特性。如果你觉得它看起来很熟悉的话,应该知道,基于SGML的语言的最著名实现就是原始的HTML。
SGML常用来定义针对HTML的文档类型定义(DTD),同时它也常用于编写XML的DTD。SGML的问题就在于,它允许出现一些奇怪的语法,这让创建HTML的解析器成为一个大难题:
1 某些起始标签不允许出现结束标签,例如HTML中img标签。包含了结束标签就会出现错误。
2 某些起始标签可以选择性出现结束标签或者隐含了结束标签,例如HTML中标签,当出现另一个标签或者某些其他标签时,便假设在这之前有一个结束标签。
3 某些起始标签要求必须出现结束标签,例如HTML中script标签。
4 标签可以以任何顺序嵌套。即使结束标签不按照起始标签的逆序出现也是允许的,例如,This is a sample string是正确的。
5 某些特性要求必须包含值,例如img src="picture.jpg"中的src特性。
6 某些特性不要求一定有值,例如[td]中的nowrap特性。
7 定义特性的两边有没有加上双引号都是可以的,所以img src="picture.jpg"和img src=picture.jpg都是允许的。
这些问题使建立一个SGML语言的解析器变成了一项艰巨的任务。判断何时应用以上规则的困难导致了SGML语言的定义一直停滞不前。以这些问题作为出发点,XML逐渐步入我们的视野。
XML去掉了之前令许多开发人员头疼的SGML的随意语法。在XML中,采用了如下的语法:
8 任何的起始标签都必须有一个结束标签。
9 可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/),例如tag /。XML解析器会将其翻译成tag/tag。
10 标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,例如this is a sample string。这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。
11 所有的特性都必须有值。
12 所有的特性都必须在值的周围加上双引号。
这些规则使得开发一个XML解析器要简便得多,而且也除去了解析SGML中花在判断何时何地应用那些奇怪语法规则上的工作。仅仅在XML出现后的前六年就衍生出多种不同的语言,包括MathML、SVG、RDF、RSS、SOAP、XSLT、XSL-FO,而同时也将HTML改进为XHTML。
如果需要关于SGML和XML具体技术上的对比,请查看W3C的注解,位于:. org/TR/NOTE-sgml-xml.html
如今,XML已经是世界上发展最快的技术之一。它的主要目的是使用文本以结构化的方式来表示数据。在某些方面,XML文件也类似于数据库,提供数据的结构化视图。这里是一个XML文件的例子:
每个XML文档都由XML序言开始,在前面的代码中的第一行便是XML序言,?xml version="1.0"?。这一行代码会告诉解析器和浏览器,这个文件应该按照前面讨论过的XML规则进行解析。第二行代码,books,则是文档元素(document element),它是文件中最外面的标签(我们认为元素(element)是起始标签和结束标签之间的内容)。所有其他的标签必须包含在这个标签之内来组成一个有效的XML文件。XML文件的第二行并不一定要包含文档元素;如果有注释或者其他内容,文档元素可以迟些出现。
范例文件中的第三行代码是注释,你会发现它与HTML中使用的注释风格是一样的。这是XML从SGML中继承的语法元素之一。
页面再往下的一些地方,可以发现desc标签里有一些特殊的语法。![CDATA[ ]]代码用于表示无需进行解析的文本,允许诸如大于号和小于号之类的特殊字符包含在文本中,而无需担心破坏XML的语法。文本必须出现在![CDATA[和]]之间才能合适地避免被解析。这样的文本称为Character Data Section,简称CData Section。
下面的一行就是在第二本书的定义之前的:
?page render multiple authors ?
虽然它看上去很像XML序言,但实际上是一种称为处理指令(processing instruction)的不同类型的语法。处理指令(以下简称PI)的目的是为了给处理页面的程序(例如XML解析器)提供额外的信息。PI通常情况下是没有固定格式的,唯一的要求是紧随第一个问号必须至少有一个字母。在此之后,PI可以包含除了小于号和大于号之外的任何字符串序列。
最常见的PI是用来指定XML文件的样式表:
这个PI一般会直接放在XML序言之后,通常由Web浏览器使用,来将XML数据以特殊的样式显示出来。
历史
XML是从1996年开始有其雏形,并向 W3C(全球信息网联盟)提案,而在1998二月发布为W3C的标准(XML1.0)。 XML的前身是SGML(The Standard Generalized Markup Language),是自IBM从60年代就开始发展的 GML(Generalized Markup Language)标准化后的名称。
GML的重要概念:
文件中能够明确的将标示与内容区隔
所有文件的标签使用方法均一致
1978年,ANSI将GML加以整理规范,发布成为SGML,1986年起为 ISO 所采用(ISO 8879),并且被广泛地运用在各种大型的文件计划中,但是SGML是一种非常严谨的文件描述法,导致过于庞大复杂(标准手册就有500多页),难以理解和学习,进而影响其推广与应用。
于是,人们对SGML进行了简化衍生出 HTML。HTML 简单,在初期没有任何定义文档外观的相关方法,仅用来在浏览器里显示网页文件。而后,随着因特网的发展,人们为了控制其文件样式,扩充了描述如何显现数据的卷标。在 Netscape 与 Microsoft 之间的浏览器大战后,HTML 标准权威性遭受重大的考验,所幸,到了HTML 4.0时,W3C 又恢复了其地位。
同时W3C意识到HTML的原罪:
不能解决所有解释数据的问题 - 像是影音文件或化学公式、音乐符号等其它型态的内容。
效能问题 - 需要下载整份文件,才能开始对文件做搜寻的动作。
扩充性、弹性、易读性均不佳。
为了解决以上问题,专家们使用SGML精简制作,并依照HTML的发展经验,产生出一套使用上规则严谨,但是简单的描述数据语言:XML。 XML是在一个这样的背景下诞生的—是不是能有一个更中立的方式,让消费端自行决定要如何消化、呈现从服务端所提供的信息?
而XML目的即在于提供一个对信息能够做精准描述的机制,藉以弥补 HTML 太过于表现导向的特质。
[编辑]用途
丰富文件(Rich Documents)- 自定文件描述并使其更丰富
属于文件为主的XML技术应用
标记是用来定义一块数据应该如何呈现
解释数据(Metadata)- 描述其它文件或在线信息
属于数据为主的XML技术应用
标记是用来说明一块资料的意义
组态档案(Configuration Files)- 描述软件的组态参数
转帖
如需操作某个XML文档,需要XML解析器。解析器会将文档载入电脑的内存中。
最基础的:
基于事件的XML简单API(Simple API for XML)称为SAX,SAX 采用的事件模型。SAX 解析器在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX 这种扩展能力得到了更好的体现。但用 SAX 解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。
基于树和节点的文档对象模型(Document Object Module)称为DOM,DOM 采用建立树形结构的方式访问。DOM 解析器把 XML 文档转化为一个包含其内容的树,并可以对树进行遍历。用 DOM 解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用 DOM 解析器的时候需要处理整个 XML 文档,所以对性能和内存的要求比较高,尤其是遇到很大的 XML 文件的时候。由于它的遍历能力,DOM 解析器常用于XML文档需要频繁的改变的服务中。
其他上层API:
基于SAX和DOM两者的:
JAXP(Java API for XML Processing)包含javax.xml.parsers和transform;其中parsers包中包括4个主要类SAXParser和SAXParserFactory类创建SAX XMLReader接口例程,DocumentBuilder和DocumentBuilderFactory类创建DOM Document接口例程。
DOM4J:一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。
XERCES:Xerces是由Apache组织所推动的一项XML文档解析开源项目,支持文档对象模型(DOM)和XML简单应用编程接口(SAX)。对于DOM解析,有DOMParser和IDOMParser;对于SAX解析,有SAXParser。它目前有多种语言版本包括JAVA、C++、PERL、COM等。
仅基于DOM的:
JDOM:Jason Hunter和Brett McLaughlin开发的项目,JDOM的设计目标就是在读和创建XML时简化DOM,取代DOM。
微软的MSXML解析器:微软的XML解析器是存在于IE 5.0或更高版本中的COM组件。一旦你安装了IE,就可使用脚本来利用解析器了。微软给我们提供XML语法解析器,一个叫做MSXML.DLL的动态链接库(C语言)
仅基于SAX的:
StAX(Streaming API for XML ):JSR-173 提出了一种面向流的新方法。其目的,简化编程,取代SAX。JDK6.0中除了DOM和SAX之外集成的又一种处理XML文档的API。
其他:
XALAN:xalan-java是一套xslt处理器,用来将XML文件转换为HTML,TEXT和XML等其他类型文件格式。支持XSLT1.0和XPATH 1.0版。开发人员可以通过命令行方式或在JAVA APPLET和SERVLET中使用,并可以作为自己开发的应用程序的类库使用。xalan-java实现的是transformation API for XML(TRaX)接口,此接口为jaxp1.2标准中的一部分。
在CLDC环境下运作的开放原始码XML分析器──kXML和NanoXML。Enhydra的KXML是一个只占很小存储空间的XML语法分析程序,对于J2ME应用程序非常适合。
在Groovy
Console
运行以下代码,结果良好。
import
groovy.xml.StreamingMarkupBuilder
//
the
original
XML
def
input
=
"
"
//
add
attributeName="attributeValue"
to
the
root
def
root
=
new
XmlSlurper().parseText(input)
root.@attributeName
=
'attributeValue'
//
get
the
modified
XML
and
check
that
it
worked
def
outputBuilder
=
new
StreamingMarkupBuilder()
String
updatedXml
=
outputBuilder.bind{
mkp.yield
root
}
assert
"
"
==
updatedXml
增加一个特性与读一个特性是一样的:
import
groovy.xml.StreamingMarkupBuilder
def
input
=
'''
'''
def
root
=
new
XmlSlurper().parseText(input)
root.@stuff
=
'new'
def
outputBuilder
=
new
StreamingMarkupBuilder()
String
result
=
outputBuilder.bind{
mkp.yield
root
}
println
result
将生成: