XML文档结构
1,XML声明
xml文档是由一组使用唯一名称标识的实体组成的。始终以一个声明开始,这个声明指定该文档遵循XML1.0的规范。XML也有一种逻辑结构,在逻辑上,文档的组成成部分包括声明,元素,注释,字符引用和处理指令。
以下是代码片段:
<?xml version="1.0" ?>
这个就是XML的声明,声明也是处理指令,在XML中,所有的处理指令都以<?开始,?>结束。<?后面紧跟的是处理指令的名称。XML处理指令要求指定一个version属性。并允许指定可选的standalone和encodeing,其中standalone是指是否允许使用外部声明,可设置为yes或no。yes是指定不使用外部声明。no为使用。encodeing是指作者使用的字符编码格式。有UTF-8,GBK,gb2312等等。
2,根元素
每个XML文件都必须有且只能有一个根元素。用于描述文档功能。可以自定义根元素。下例中的root为根元素。 以下是代码片段:
<root>...................</root>
3,XML代码
根据应用需要创建自定义的元素和属性。标签包括尖括号以及尖括号中的文本。元素是XML内容的基本单元。元素包括了开始标签、结束标签和标签之间的内容。
以下是代码片段:
<title>XML是可扩展标记语言</title>
整行统称为元素,其中<title></title>为标签,XML是可扩展标记语言是字符数据
XML的标记有:标签,注释,处理指令,DTD和引用等。
注释
在XML中,注释与HTML的一样,都是用<!-- 注释 -->指定注释。要遵循以下规则:
在注释中不应包含有“-”“—”等字符,以免XML解释器产生混淆。
注释不能放在标签中
注释不能写在第一行。第一行是XML声明。
注释不能嵌套
可跨行注释,与java中的/**/注释块功能一样。
处理指令
凡是以<?开始, ?>结束的都是处理指令。XML声明就是一个处理指令。
标签间的字符数据的分类
标签间的字符数据可以是除了“<”以外的任何合法(Unicode)字符。“<”字符是预留作为标签的开始字符。字符数据分以下两类:
PCDATA(是指将要通过解析器进行解析的文本)
CDATA (是指不要通过解析器进行解析的文本)
其中不允许中CDATA块之内使用字符串“]]>”,因为它表示CDATA块的结束。
实体
实体可以是常用的短语,键盘字符,文件,数据库记录或任何包含数据的项。在XML中,有时实体内包含了些字符,如&,<,>,",'等。这些均需要对其进行转义,否则会对XML解释器生成错误。
字符
转义后字符
<
<
>
>
"
"
'
'
&
&
在XML中出现以上字符的,均需要转义才能通过。
实体格式如下: 以下是代码片段:
<!ENTITY 实体引用名 "引用内容">
实体又分两类:
1,一般实体(格式:&实体引用名;)
2,参数实体(格式:%实体引用名;)
一般实体,可以在XML文档中的任何位置出现的实体称为一般实体。实体可以声明为内部实体还是外部实体。外部实体分SYSYTEM及PUBLIC两种。SYSYTEM引用本地计算机,PUBLIC引用公共计算机,外部实体格式如下:
<!ENTITY 引用名 SYSTEM(PUBLIC) "URI地址">
管理实体引用的规则包括:
引用实体前,必须先在XML文档中声明该实体。
实体引用不应含有任空空格。例如:& title; &title ;都是不对的。
实体引用的XML文件必须是格式良好的。
实体引用可以替代常规字符数据,也可以在标签属性中使用实体引用。如
<title value="&titleValue" />
DOCTYPE声明
在XML文档中,<!DOCTYPE[...]>声明跟在XML声明的后面。实体也必须在DOCTYPE声明中声明。语法如下:
以下是代码片段:
<?xml version="1.0" unicode="UTF-8">
<!DOCTYPE[
.....在此声明实体<!ENTITY 实体引用名 "引用内容">
]>
代码例子:
以下是代码片段:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE root[
<!ENTITY titleValue "引用字符1">
<!ENTITY titleValue2 "引用字符2">
]>
<root>
<title value="&titleValue;"> &titleValue; </title>
<title2>
<value><a>&titleValue2;</a></value>
</title2>
</root>
在IE是打开XML文件显示为:
以下是代码片段:
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE root (View Source for full doctype...)>
[url=file:///C:/Documents%20and%20Settings/Administrator/桌面/xml/test.xml#]-[/url] <root>
<title value="引用字符1">引用字符1</title>
[url=file:///C:/Documents%20and%20Settings/Administrator/桌面/xml/test.xml#]-[/url] <title2>
[url=file:///C:/Documents%20and%20Settings/Administrator/桌面/xml/test.xml#]-[/url] <value>
<a>引用字符2</a>
</value>
</title2>
</root>
当满足以下条件时,是为格式良好的XML文档:
至少需要一个元素
XML标签区分大小写
应正确使用结束标签
正确的嵌套
应使用合法标签:标签必须以一个字母,下划线,或冒号开始,后面可以跟字母,数字,句号,冒号,下划线,连字符的组合。但不能有空格。也不应以XML开头,因为XML是保留字。
标记名称长度
应定义有效属性
应验证文档
在XML中,所有的值都被被为字符串。
解析器
解析器有两种类型:
1,非验证解析器:它检查文档的格式是否良好
2,验证解析器:使用DTD检查文档的有效性(分别有Apache的Xerces和Oracle XML Parser)
DTD:(Document)文档类型结构
DTD的一般结构如下:
<!DOCTYPE dtd-name[
<!ELEMENT element-name (element-content type)>
<!ATTLIST element-name attribute-name attribute-type default-value>
]>
element-name :元素名
element-content type:元素类型
attribute-name :属性名
attribute-type:属性类型
default-value:默认值
空元素:EMPTY,指定该元素没有子元素或字符数据。<!ELEMENT element-name (EMPTY)>
带数据的元素:
<!ELEMENT element-name (#CDATA)> 包含有不会通过解析器解析的数据
<!ELEMENT element-name (#PCDATA)> 包含有要通过解析器解析的数据
<!ELEMENT element-name (ANY)> 包含零个或零个以上任何声明类型的子元素以及字符数据
带有子元素的元素
<!ELEMENT element-name (child-element-name1,child-element-name2....)> 多个子元素时用,号分隔
声明相同元素只出现一次
<!ELEMENT element-name (child-element-name)>
声明相同元素只出现零次或一次
<!ELEMENT element-name (child-element-name?)>
声明相同元素只出现一次或多次
<!ELEMENT element-name (child-element-name+)>
声明相同元素只出现零次或多次
<!ELEMENT element-name (child-element-name*)>
属性声明:
Default属性值:默认属性值
<!ATTLIST element-name attribute-name CDATA "default-value">
Implied属性值:可有可无
<!ATTLIST element-name attribute-name #IMPLIED>
Required属性值:指定属性为必须的
<!ATTLIST element-name attribute-name #REQUIRED>
Fixed属性值:属性值是固定的,使作者不能更改
<!ATTLIST element-name attribute-name CDATA(PCDATA) #FIXED "value">
Enumerated属性类型:使属性值成为一组固定合法值的一员
<!ATTLIST element-name attribute-name (eval1 | eval2 | ....) "default-value">
DTD示例:
内部DTD 以下是代码片段:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE root[
<!ELEMENT root (book*)>
<!ELEMENT book (name,title,versions,address)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT versions (#PCDATA)>
<!ELEMENT address (#PCDATA)>
<!ATTLIST title value CDATA #REQUIRED>
<!ATTLIST address value CDATA #FIXED "中国广东">
<!ATTLIST versions value (1.0 | 2.0 ) "1.0">
<!ENTITY addr "中国广东珠海">
]>
<root>
<book>
<name>XML</name>
<title value="a">xml可扩展语言</title>
<versions value="1.0">1.0</versions>
<address value="中国广东">&addr;</address>
</book>
<book>
<name>XML</name>
<title value="">xml可扩展语言</title>
<versions>1.0</versions>
<address value="中国广东">&addr;</address>
</book>
</root>
外部DTD使用语法如下:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE 根元素的名称 SYSTEM "外部DTD文件URI">
<root>........<root>
此处的外部DTD文件内容为: 以下是代码片段:
<?xml version="1.0" encoding="GBK"?>
<!ELEMENT root (book*)>
<!ELEMENT book (name,title,versions,address)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT versions (#PCDATA)>
<!ELEMENT address (#PCDATA)>
<!ATTLIST title value CDATA #REQUIRED>
<!ATTLIST address value CDATA #FIXED "中国广东">
<!ATTLIST versions value (1.0 | 2.0 ) "1.0">
<!ENTITY addr "中国广东珠海">
保存为dtd文件。
在网上搜到的Xpath教程!
基本的XPath语法类似于在一个文件系统中定位文件,如果路径以斜线 / 开始, 那么该路径就表示到一个元素的绝对路径
/AAA
选择根元素AAA
<AAA>
<BBB/>
<CCC/>
<BBB/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC/>
</AAA>
/AAA/CCC
选择AAA的所有CCC子元素
<AAA>
<BBB/>
<CCC/>
<BBB/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC/>
</AAA>
/AAA/DDD/BBB
选择AAA的子元素DDD的所有子元素
<AAA>
<BBB/>
<CCC/>
<BBB/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC/>
</AAA>
如果路径以双斜线 // 开头, 则表示选择文档中所有满足双斜线//之后规则的元素(无论层级关系)
//BBB
选择所有BBB元素
<AAA>
<BBB/>
<CCC/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
</CCC>
</AAA>
//DDD/BBB
选择所有父元素是DDD的BBB元素
<AAA>
<BBB/>
<CCC/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
</CCC>
</AAA>
星号 * 表示选择所有由星号之前的路径所定位的元素
/AAA/CCC/DDD/*
选择所有路径依附于/AAA/CCC/DDD的元素
<AAA>
<XXX>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</XXX>
<CCC>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</CCC>
<CCC>
<BBB>
<BBB>
<BBB/>
</BBB>
</BBB>
</CCC>
</AAA>
/*/*/*/BBB
选择所有的有3个祖先元素的BBB元素
<AAA>
<XXX>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</XXX>
<CCC>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</CCC>
<CCC>
<BBB>
<BBB>
<BBB/>
</BBB>
</BBB>
</CCC>
</AAA>
//*
选择所有元素
<AAA>
<XXX>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</XXX>
<CCC>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</CCC>
<CCC>
<BBB>
<BBB>
<BBB/>
</BBB>
</BBB>
</CCC>
</AAA>
方块号里的表达式可以进一步的指定元素, 其中数字表示元素在选择集里的位置, 而last()函数则表示选择集中的最后一个元素.
/AAA/BBB[1]
选择AAA的第一个BBB子元素
<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
</AAA>
/AAA/BBB[last()]
选择AAA的最后一个BBB子元素
<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
</AAA>
属性通过前缀 @ 来指定
//@id
选择所有的id属性
<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>
//BBB[@id]
选择有id属性的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>
//BBB[@name]
选择有name属性的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>
//BBB[@*]
选择有任意属性的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>
//BBB[not(@*)]
选择没有属性的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>
属性的值可以被用来作为选择的准则, normalize-space函数删除了前部和尾部的空格, 并且把连续的空格串替换为一个单一的空格
//BBB[@id='b1']
选择含有属性id且其值为'b1'的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
</AAA>
//BBB[@name='bbb']
选择含有属性name且其值为'bbb'的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
</AAA>
//BBB[normalize-space(@name)='bbb']
选择含有属性name且其值(在用normalize-space函数去掉前后空格后)为'bbb'的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
</AAA>
count()函数可以计数所选元素的个数
//*[count(BBB)=2]
选择含有2个BBB子元素的元素
<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>
//*[count(*)=2]
选择含有2个子元素的元素
<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>
//*[count(*)=3]
选择含有3个子元素的元素
<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>
name()函数返回元素的名称, start-with()函数在该函数的第一个参数字符串是以第二个参数字符开始的情况返回true, contains()函数当其第一个字符串参数包含有第二个字符串参数时返回true.
//*[name()='BBB']
选择所有名称为BBB的元素(这里等价于//BBB)
<AAA>
<BCC>
<BBB/>
<BBB/>
<BBB/>
</BCC>
<DDB>
<BBB/>
<BBB/>
</DDB>
<BEC>
<CCC/>
<DBD/>
</BEC>
</AAA>
//*[starts-with(name(),'B')]
选择所有名称以"B"起始的元素
<AAA>
<BCC>
<BBB/>
<BBB/>
<BBB/>
</BCC>
<DDB>
<BBB/>
<BBB/>
</DDB>
<BEC>
<CCC/>
<DBD/>
</BEC>
</AAA>
//*[contains(name(),'C')]
选择所有名称包含"C"的元素
<AAA>
<BCC>
<BBB/>
<BBB/>
<BBB/>
</BCC>
<DDB>
<BBB/>
<BBB/>
</DDB>
<BEC>
<CCC/>
<DBD/>
</BEC>
</AAA>
string-length函数返回字符串的字符数,你应该用<替代<, 用>代替>
//*[string-length(name()) = 3]
选择名字长度为3的元素
<AAA>
<Q/>
<SSSS/>
<BB/>
<CCC/>
<DDDDDDDD/>
<EEEE/>
</AAA>
//*[string-length(name()) < 3]
选择名字长度小于3的元素
<AAA>
<Q/>
<SSSS/>
<BB/>
<CCC/>
<DDDDDDDD/>
<EEEE/>
</AAA>
//*[string-length(name()) > 3]
选择名字长度大于3的元素
<AAA>
<Q/>
<SSSS/>
<BB/>
<CCC/>
<DDDDDDDD/>
<EEEE/>
</AAA>
多个路径可以用分隔符 | 合并在一起
//CCC | //BBB
选择所有的CCC和BBB元素
<AAA>
<BBB/>
<CCC/>
<DDD>
<CCC/>
</DDD>
<EEE/>
</AAA>
/AAA/EEE | //BBB
选择所有的BBB元素和所有是AAA的子元素的EEE元素
<AAA>
<BBB/>
<CCC/>
<DDD>
<CCC/>
</DDD>
<EEE/>
</AAA>
/AAA/EEE | //DDD/CCC | /AAA | //BBB
可以合并的路径数目没有限制
<AAA>
<BBB/>
<CCC/>
<DDD>
<CCC/>
</DDD>
<EEE/>
</AAA>
child轴(axis)包含上下文节点的子元素, 作为默认的轴,可以忽略不写.
/AAA
等价于 /child::AAA
<AAA>
<BBB/>
<CCC/>
</AAA>
/child::AAA
等价于/AAA
<AAA>
<BBB/>
<CCC/>
</AAA>
/AAA/BBB
等价于/child::AAA/child::BBB
<AAA>
<BBB/>
<CCC/>
</AAA>
/child::AAA/child::BBB
等价于/AAA/BBB
<AAA>
<BBB/>
<CCC/>
</AAA>
/child::AAA/BBB
二者都可以被合并
<AAA>
<BBB/>
<CCC/>
</AAA>
descendant (后代)轴包含上下文节点的后代,一个后代是指子节点或者子节点的子节点等等, 因此descendant轴不会包含属性和命名空间节点.
/descendant::*
选择文档根元素的所有后代.即所有的元素被选择
<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>
/AAA/BBB/descendant::*
选择/AAA/BBB的所有后代元素
<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>
//CCC/descendant::*
选择在祖先元素中有CCC的所有元素
<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>
//CCC/descendant:DD
选择所有以CCC为祖先元素的DDD元素
<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>
parent轴(axis)包含上下文节点的父节点, 如果有父节点的话
//DDD/parent::*
选择DDD元素的所有父节点
<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>
ancestor轴(axis)包含上下节点的祖先节点, 该祖先节点由其上下文节点的父节点以及父节点的父节点等等诸如此类的节点构成,所以ancestor轴总是包含有根节点,除非上下文节点就是根节点本身.
/AAA/BBB/DDD/CCC/EEE/ancestor::*
选择一个绝对路径上的所有节点
<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>
//FFF/ancestor::*
选择FFF元素的祖先节点
<AAA>
<BBB>
<DDD>
<CCC>
<DDD/>
<EEE/>
</CCC>
</DDD>
</BBB>
<CCC>
<DDD>
<EEE>
<DDD>
<FFF/>
</DDD>
</EEE>
</DDD>
</CCC>
</AAA>
following-sibling轴(axis)包含上下文节点之后的所有兄弟节点
/AAA/BBB/following-sibling::*
<AAA>
<BBB>
<CCC/>
<DDD/>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//CCC/following-sibling::*
<AAA>
<BBB>
<CCC/>
<DDD/>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
preceding-sibling 轴(axis)包含上下文节点之前的所有兄弟节点
/AAA/XXX/preceding-sibling::*
<AAA>
<BBB>
<CCC/>
<DDD/>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//CCC/preceding-sibling::*
<AAA>
<BBB>
<CCC/>
<DDD/>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
following轴(axis)包含同一文档中按文档顺序位于上下文节点之后的所有节点, 除了祖先节点,属性节点和命名空间节点
/AAA/XXX/following::*
<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
<DDD>
<EEE/>
</DDD>
</ZZZ>
<FFF>
<GGG/>
</FFF>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//ZZZ/following::*
<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
<DDD>
<EEE/>
</DDD>
</ZZZ>
<FFF>
<GGG/>
</FFF>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
following轴(axis)包含同一文档中按文档顺序位于上下文节点之前的所有节点, 除了祖先节点,属性节点和命名空间节点
/AAA/XXX/preceding::*
<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//GGG/preceding::*
<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
descendant-or-self 轴(axis)包含上下文节点本身和该节点的后代节点
/AAA/XXX/descendant-or-self::*
<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//CCC/descendant-or-self::*
<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
ancestor-or-self 轴(axis)包含上下文节点本身和该节点的祖先节点
/AAA/XXX/DDD/EEE/ancestor-or-self::*
<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//GGG/ancestor-or-self::*
<AAA>
<BBB>
<CCC/>
<ZZZ>
<DDD/>
</ZZZ>
</BBB>
<XXX>
<DDD>
<EEE/>
<DDD/>
<CCC/>
<FFF/>
<FFF>
<GGG/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
ancestor, descendant, following, preceding 和self轴(axis)分割了XML文档(忽略属性节点和命名空间节点), 不能交迭, 而一起使用则包含所有节点
//GGG/ancestor::*
<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//GGG/descendant::*
<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//GGG/following::*
<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//GGG/preceding::*
<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//GGG/self::*
<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
//GGG/ancestor::* | //GGG/descendant::* | //GGG/following::* | //GGG/preceding::* | //GGG/self::*
<AAA>
<BBB>
<CCC/>
<ZZZ/>
</BBB>
<XXX>
<DDD>
<EEE/>
<FFF>
<HHH/>
<GGG>
<JJJ>
<QQQ/>
</JJJ>
<JJJ/>
</GGG>
<HHH/>
</FFF>
</DDD>
</XXX>
<CCC>
<DDD/>
</CCC>
</AAA>
div运算符做浮点除法运算, mod运算符做求余运算, floor函数返回不大于参数的最大整数(趋近于正无穷), ceiling返回不小于参数的最小整数(趋近于负无穷)
//BBB[position() mod 2 = 0 ]
选择偶数位置的BBB元素
<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<CCC/>
<CCC/>
<CCC/>
</AAA>
//BBB[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]
选择中间的BBB元素
<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<CCC/>
<CCC/>
<CCC/>
</AAA>
//CCC[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]
选择中间的CCC元素
<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<CCC/>
<CCC/>
<CCC/>
</AAA>