Part I -The Basics: XML, DTD, and XSchema
HTML
在1989年,欧洲核研究组织的工程师蒂姆·伯纳斯-李无意中发明了万维网,形式为其互联网协议超文本传输协议(HTTP)及其文档格式超文本标记语言(HTML)。
HTML扩展了标准通用标记语言(SGML),这是一个定义文档的通用标记语言的国际标准(ISO 8879:1986),通过添加超链接标签。它自身在1992年成为了一个标准,即HTML 1.0。
1996年,来自Sun Microsystems的Jon Bosak、来自滑铁卢大学和Netscape的Tim Bray等人在万维网联盟(W3C)开始设计一个SGML的轻量版,称为可扩展标记语言(XML)。最早的标记语言SCRIPT由来自麻省理工学院的Stuart Madnick为IBM设计,发表于1968年。
XML文件
- XML是一种用于文档的标记语言。
- XML自1998年以来是一个国际标准,W3C发布了XML 1.0规范。
- XML旨在存储和传输数据(Web数据交换)。
- XML设计既适合人类阅读,也适合机器阅读。
- XML是无模式的。
以下是一个从“Mondial”集合下载的、经过改编的XML文档。
XML技术
W3C推广伴随标准和技术。
- DTD、XML Schema、Relax NG;
- DOM与JavaScript Ajax;
- XPath、XSLT和XQuery;
- XML服务(WSDL、SOAP、RDF、RSS等);
- 基于XML的标记语言(SVG、XBRL、HTML5等);
- 关系数据库管理系统中的XML领域;
- 以及用于Web文档的XHTML和XHTML5。
XML是一个“标准中的标准”(就像有“编译器中的编译器”一样)。
- 可缩放矢量图形(SVG)是一种基于XML的矢量图像格式。
- 数学标记语言(MathML)是XML用于数学公式的应用。
- 材料标记语言(MatML)是XML用于材料属性数据的应用。
- 可扩展商业报告语言(XBRL)是XML用于财务信息的应用。
- 图形标记语言(GraphML)是XML用于图形的应用。
XML语言
定义
从概念上讲,一个XML文档表示一个带标签的、非等级的、有序的树结构,由节点组成,其中一个是根,以及表示子节点或父节点(以及传递性的后代和祖先)关系的边,并且兄弟节点之间是有序的。
一个XML文档表示一个带标签的、非等级的、有序的树:
- 带标签意味着每个节点都附加了一些注释,即标签。
- 非等级意味着节点的子节点数量没有预先限定。
- 有序意味着每个节点的子节点之间存在顺序。
不同实现(文档对象模型、XQuery数据模型、Xpath数据模型等)之间对数据模型的细节和节点的描述没有进一步的共识。
几乎,一个XML文档是一个带有标记标签和其他元信息的Unicode文本(文件或字符串),这些元信息表示元素、属性和其他节点。
与HTML不同,XML是区分大小写的。
一个XML文档可能以一个序言开始,该序言可能包含一个XML声明和DTD信息。
序言中可以包含一个XML声明。
如果包含了XML声明,它必须位于XML文档的第一行的第一个位置。如果包含了XML声明,它必须包含版本号属性。如果在XML声明中声明了所有属性,它们必须按照上面显示的顺序放置。XML声明必须使用小写字母(编码声明除外)。如果在XML文档中使用了任何在外部DTD中引用或定义的元素、属性或实体,则必须包含 standalone="no"。如果文件以Unicode字节顺序标记[0xFF 0xFE] 或 [0xFE 0xFF] 开头,则文档被认为是UTF-16的,否则,它是UTF-8的。
在XML文档中,有几个符号不能直接使用,因为它们会被解析器误解。
Tags 标签
一个XML文档可以包含注释和处理指令。
标签的组成
标签名不能包含任何字符!"#$%&’()*+,/;<=>?@[]^‘{|}~,也不能包含空格字符,并且不能以=、.、三个字母的“xml”(无论是小写、大写还是混合大小写),或数字开头。
- 一个开放标签的形式是<tag_name>,例如<sldMasterIdLst>;
- 一个空元素标签的形式是<tag_name/>,例如<notesSz/>;
- 一个关闭标签的形式是</tag_name>,例如</sldMasterIdLst>;
元素和良好格式的 XML
一对具有相同名称的开放和关闭标签限定了一个元素。一个空元素标签限定了一个空元素(尽管它可能有属性)。
一个XML文档是格式良好的当且仅当
- 没有特殊语法字符如<和&出现,除了它们的标记划分角色;
- 元素必须正确嵌套:它们必须被打开和关闭,并且不能重叠;
- 有一个单一的元素,即根元素,包含所有其他元素。
在开放和空元素标签中的标签名后面可以跟随一个属性列表及其值。<sldSz cx="9144000" cy="6858000" type="screen4x3"/>;
标签名可以被一个名称空间名字前缀,用冒号分隔,例如<p:custDataLst>。
文字部分
通常,元素的内容是被解析来分析其结构的。
问题是:如果我们不希望内容被解析怎么办?
解决方案:对所有特殊符号使用实体;或者使用文字区段来阻止解析。
键入与否
DTD
默认情况下,XML是没有模式的。然而,自从其第一个工作草案以来,XML包含了一个内置的模式语言:文档类型定义(Document Type Definition,简称DTD)。
内部和外部 DTD
- DTD可以是外部的或内部的。
- 也可以使用URI外部指定DTD。
- 例如,以下DTD指示XML应该遵循XHTML(有效HTML)的结构。
内部DTD
可以在XML文档的序言中用关键字DOCTYPE声明DTD。
格式规范与有效
一个格式良好的XML文档如果符合其DTD,就被认为是有效的。
实体和引用
实体用于文档的物理组织。在文档类型定义中声明一个实体,然后引用它。
命名空间
一个特定的标签,例如job,可能在不同的上下文中表示不同的概念,例如招聘机构或计算机ASP(应用服务提供商)。使用命名空间的概念来区分它们。
DTD 与 XML 模式
DTD:旧式打字,仍然非常使用。
XML模式:更现代(在XML中),例如在Web服务中使用。
XML还有其他模式语言,如RELAX NG(REgular LAnguage for XML Next Generation)。
Part II - XPath
XPath
- XPath是XML路径语言。
- XPath语言范式基于遍历XML树的思想。
- XPath表达式由位置路径和函数组成。
- XPath用于XML模式中的唯一性和范围描述,用于XSLT中的模式匹配和选择,以及用于XQuery中的选择和迭代,以及其他语言中。
在XPath数据模型中,XML树可以有六种类型的节点。
- 元素节点;
- 属性节点;
- 文本节点:文本节点对应于被标记的实际信息片段。
- 注释节点;
- 处理指令节点;
- 根节点:每个XML树以一个单一的根节点开始。根节点的子节点可以是任意数量的注释和处理指令节点,以及正好一个元素节点。不要将根节点和根元素混淆。这个根节点可以被视为文档(在eXist-db中是doc("..."))。
位置路径和步骤
位置路径
- 位置路径或路径表达式在其缩写或非缩写语法中评估为一系列节点(按文档顺序或反向顺序)。
- 位置路径是一系列位置步骤的序列。位置步骤由斜杠分隔。
- 如果位置路径以斜杠开头,即它从文档的根开始,则该路径是绝对的。
例如:
或者,等价的,使用简写语法:
- 如果位置路径以位置步骤开始,即它从当前节点开始,则该路径是相对的。
例如:
或者,等价的,使用简写语法:
位置步骤
位置步骤有三部分:
-
轴,指定由位置步骤选择的节点与上下文节点之间的树关系,
-
节点测试,指定位置步骤选择的节点的节点类型和扩展名,以及
-
零个或多个谓词,使用任意表达式进一步细化位置步骤选择的节点集。
轴
1. child选择当前节点的所有子节点
请注意,在第一个/之前有一个“不可见”的根节点,其子节点是A。
2. escendant选择当前节点的所有后代节点
3. parent选择当前节点的父节点
4. preceding-sibling和following-sibling分别选择当前节点的所有前导兄弟姐妹节点和后续兄弟姐妹节点。
5. preceding和following分别选择所有前导(除属性节点和祖先节点外)和后续节点,按它们在文档中出现的顺序,相对于当前节点。
让我们考虑一个带有属性的例子。
6. attribute选择当前节点的所有属性(我们可以使用data()函数访问元素或属性的内容。)
节点测试
节点测试主要的XPath节点测试有:
- 节点名称选择具有给定名称的节点(取决于轴:通常是元素名称和属性轴的属性名称);
- *根据轴选择元素或属性类型的节点;
- node()选择所有类型的节点;
- text()选择文本类型的节点;
- comment()选择注释类型的节点;
- processing-instruction()选择处理指令类型的节点。
谓词
- 谓词是路径上的条件。
- 谓词中的相对路径表达式从当前节点开始。
- 如果谓词内的路径存在或表达的条件为真,则谓词为真。
- 谓词使用运算符(=,<,>,<=,>=,!=)。
- 谓词使用连接词(or,and,not,|)。
- 可以使用括号。谓词使用函数和操作(+,-,*,/,mod,contains(),sum())。
- 可以使用括号。谓词位于方括号之间。
谓词具有以下形式之一:
[attribute::car_code]
元素具有属性car_code;[attribute::car_code="AL"]
元素具有属性car_code,其值为AL(也可以使用>, <, <=, >=和!=);[child::country]
元素具有子元素country(可以是路径);[child::country="Albania"]
元素具有子元素country(可以是路径),其值为Albania(也可以使用>, <, <=, >=和!=);|
(竖直条)用于在路径表达式中表示析取(三思!);and
用于在谓词中表示析取;or
用于在谓词中表示析取;not()
用于在谓词中表示否定。
析取
谓词可以沿任何路径使用。
连接词、运算符、操作、函数、路径和谓词可以在谓词中使用。
析取路径可用于任何路径表达式。
速记
位置路径速记示例
以下是一些常用的简写表示法,代替完整的语法(axis::node test)。
- 绝对位置路径
/A
选择当前节点的子元素A(child轴的简写,child); - 相对位置路径
A
选择当前节点的子元素A(child轴的简写,child); - 绝对或相对位置路径
//B
选择当前节点的后代元素B(descendant轴的简写,descendant); - 位置路径
.
选择当前节点; - 位置路径
..
选择当前节点的父节点; @a
选择当前元素的a属性(attribute轴的简写,attribute);- 通配符
*
和@*
分别匹配任何元素节点和任何属性节点。
Part III 实用语言: XQuery 和 XSLT
Xquery
- XQuery 1.0是XPath 2.0的严格超集。
- 每个XPath 2.0表达式都直接是XQuery 1.0表达式(一个查询)。
- 额外的表达能力是能够从不同源中联接信息并生成新的XML片段。
我们考虑XQuery FLOWR表达式。
for
选择一系列节点;let
将一系列绑定到一个变量;where
过滤节点;order by
对节点排序;return
返回结果(对每个节点评估一次);
让我们使用以下文档来说明XQuery查询。
for
和return
:for
迭代从指定文档通过XPath或XQuery表达式选定的节点。它使用XQuery变量。return
返回结果。XQuery代码可以包含XML(因此也包括XHTML)。
let
:let
将XQuery变量绑定到XPath或XQuery表达式的结果,到一组节点。
where
:where
过滤与XPath或XQuery谓词一致的节点。
order by
:order by
对结果进行排序。
聚合:XQuery还支持带有group by的聚合函数。
连接:使用嵌套的for,XQuery可以连接几个XML文档(在示例中是一个文档本身)。
XSLT
- XSLT(可扩展样式表语言转换)是一种导航、查询和转换文档的语言,特别是XML。
- XSLT使用(XPath的一个子集)。
XSLT可以在XSL样式表中使用,并作为内部样式表嵌入到XML文档的根元素下,如下所示,带有相应的处理指令(也可以是外部样式表)。
让我们使用以下文档来说明XQuery查询。
实例
for-each
:for-each
迭代从指定文档通过XPath表达式选定的节点。- XSLT代码可以包含XML(因此也包括XHTML)。
- XSLT代码被转换为结果。
template
:template
定义了模板。模板适用于与match路径表达式匹配的节点,如果可用。apply-templates
:apply-templates
指示XSLT处理器找到适当的模板来应用于所有节点或选择路径表达式匹配的节点,如果可用,或它们的后代。
- XSLT提供了三种编程风格:XPath,命令式编程和模板匹配。