📄 0703-0400.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0071)http://162.105.170.55/ASPs/GetLearningArticleTemp.asp?section=0703-0400 -->
<HTML><HEAD><TITLE>XML中国论坛 - 初学进阶 - 7.3.4 位置步</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<STYLE type=text/css>TABLE {
FONT-SIZE: 9pt; COLOR: black; LINE-HEIGHT: 15pt; FONT-FAMILY: "宋体"
}
.pt9 {
FONT-SIZE: 9pt; COLOR: black; LINE-HEIGHT: 15pt; FONT-FAMILY: "宋体"
}
.pt10 {
FONT-WEIGHT: 700; FONT-SIZE: 10pt; LINE-HEIGHT: 18pt; FONT-FAMILY: "宋体"
}
.TempOutline {
FONT-SIZE: 9pt; MARGIN-LEFT: 15pt; COLOR: #666666; TEXT-INDENT: -28pt; LINE-HEIGHT: 15pt; FONT-FAMILY: "宋体"; TEXT-DECORATION: none
}
.TempOutline1 {
FONT-SIZE: 9pt; MARGIN-LEFT: 24pt; COLOR: #666666; TEXT-INDENT: -36pt; LINE-HEIGHT: 15pt; FONT-FAMILY: "宋体"; TEXT-DECORATION: none
}
.Outline {
FONT-SIZE: 9pt; MARGIN-LEFT: 15pt; TEXT-INDENT: -28pt; LINE-HEIGHT: 15pt; FONT-FAMILY: "宋体"; TEXT-DECORATION: none
}
.Outline1 {
FONT-SIZE: 9pt; MARGIN-LEFT: 24pt; TEXT-INDENT: -36pt; LINE-HEIGHT: 15pt; FONT-FAMILY: "宋体"; TEXT-DECORATION: none
}
.Outline11 {
FONT-SIZE: 9pt; MARGIN-LEFT: 38pt; TEXT-INDENT: -50pt; LINE-HEIGHT: 15pt; FONT-FAMILY: "宋体"; TEXT-DECORATION: none
}
.passage0 {
FONT-SIZE: 9pt; MARGIN-LEFT: 15pt; TEXT-INDENT: -28pt; LINE-HEIGHT: 15pt; FONT-FAMILY: "宋体"; TEXT-DECORATION: none
}
.passage1 {
FONT-SIZE: 9pt; MARGIN-LEFT: 24pt; TEXT-INDENT: -36pt; LINE-HEIGHT: 15pt; FONT-FAMILY: "宋体"; TEXT-DECORATION: none
}
.passage11 {
FONT-SIZE: 9pt; MARGIN-LEFT: 38pt; TEXT-INDENT: -50pt; LINE-HEIGHT: 15pt; FONT-FAMILY: "宋体"; TEXT-DECORATION: none
}
.passage111 {
FONT-SIZE: 9pt; MARGIN-LEFT: 51pt; TEXT-INDENT: -64pt; LINE-HEIGHT: 15pt; FONT-FAMILY: "宋体"; TEXT-DECORATION: none
}
</STYLE>
<META content="Microsoft FrontPage 5.0" name=GENERATOR></HEAD>
<BODY vLink=#000000 aLink=#000000 link=#000000 leftMargin=0 topMargin=0
onload=""><!-- 以下为主体内容 -->
<div align="center">
<center>
<TABLE width="100%" border=0 style="border-collapse: collapse" bordercolor="#111111" cellpadding="0" cellspacing="0">
<TBODY>
<TR vAlign=top>
<TD width=41 rowSpan=2></TD>
<TD vAlign=center width="549" >
<p align="center"><IMG height=33
src="image/title_learner.gif" width=226></TD>
<TD width=41 rowSpan=2></TD>
</TR>
<TR vAlign=top>
<TD width="549" ><!-- 正文内容 -->
<DIV class=pt10><B>7.3.4 位置步</B></DIV>
<DIV></DIV><BR>
<DIV class=pt9>
<P>位置步用于表示一个相对于已知位置的位置,这个已知位置可能是一个绝对位置,也可能是一个计算结果,由所处的上下文(context)决定,这个位置称为上下文节点(context
node)。如前所述,位置步的构成包括三个部分:
<UL>
<LI>关键字,有且仅有一个,用于表示结果节点与上下文节点在文件树中的关系;
<LI>节点测试,有且仅有一个,用于表示结果节点的类型或扩展名;
<LI>谓词,零到多个,用于限制结果的任意表达式。 </LI></UL>
<P>位置步首先利用关键字和节点测试计算,得到初始结果集,然后依次利用谓词进行过滤。初始结果集中满足所有谓词的就是返回结果。初始结果集中的元素与上下文节点构成关键字关系,而且具有节点测试指定的类型或名称,例如child::sepc表示上下文节点的所有sepc子元素。在对初始结果集进行过滤时,首先用第一个谓词对初始结果集进行过滤,返回一个结果集,在此基础上利用第二个谓词过滤,依次类推,直到得到最后的结果集。
<OL>
<LI><STRONG>关键字</STRONG> </LI></OL>
<P>前面的例子提到了几个关键字child、descendent,其他的关键字还有ancestor、self、ancestor-or-self、paren、descendant-or-self、attribute、following、preceding、following-sibling、preceding-sibling等,它们的含义与XPath中的对应关键字一样,请读者参考4.3.3节,这里不再赘述。这些关键字的返回结果总是节点或节点构成的集合,节点的类型可以是元素、属性、注释、文本、处理指令等,但不能是命名空间。</P>
<P>由于位置步总是计算相对于上下文节点的位置,因此需要一个绝对位置,表示第一个位置步的上下文节点。关键字的运算取决于上下文节点,如果上下文节点有多个,它将对上下文节点逐一进行计算。XPointer可以利用XPath的绝对位置定位方法进行定位,包括利用"/"表示根节点和用id()表示具有给定ID值的元素。</P>
<P>关键字具有自己的基本节点类型,基本节点类型主要用于节点测试。对于那些可以包含元素的关键字,如child、parent等,其基本节点类型为元素类型,在上面提到的12个关键字中,除了attribute以外,其他关键字的基本节点类型都是元素类型。而关键字attribute关键字的基本节点类型是属性类型。
<OL start=2>
<LI><STRONG>节点测试</STRONG> </LI></OL>
<P>节点测试用于测试节点类型或节点名称,只有那些满足节点测试的节点才会保留在初始的结果集中,以待下一步的谓词过滤。</P>
<P>在很多情况下,节点测试是一个名称,此时要求候选节点的类型与关键字的基本节点类型相同,并且具有指定的名称。因此对除attribute以外的关键字,如果节点测试是一个名称,结果将返回一个具有指定名称的元素集合,而对attribute关键字,同样的节点测试将返回具有指定名称的属性。例如:child::sepc返回上下文节点内的所有名为sepc的子节点,如果上下文节点没有名为sepc的子节点,结果将返回空集;而attribute::href将返回上下文节点的href属性,类似地,如果上下文节点不包括href属性,结果也会返回空集。</P>
<P>其他的节点测试还有:
<UL>
<LI>*;
<LI>node();
<LI>comment();
<LI>processing-instruction();
<LI>text(); </LI></UL>
<P>通配符*表示所有的元素,它不考虑元素的名称,只要元素与上下文节点满足关键字所指定的关系即可,例如child::*表示上下文节点的所有子节点。通配符*只选择元素类型。如果你希望选择所有节点,可以用node()表示。通配符*还可用于名称内部,用于过滤特定命名空间的元素和属性。比如:</P>
<DIV align=center>
<CENTER>
<TABLE width="80%" border=1>
<TBODY>
<TR>
<TD
width="100%">child::*:spec<BR>attribute::xlink:*</TD></TR></TBODY></TABLE></CENTER></DIV>
<P>上面的第一个例子表示上下文节点内所有命名空间下名为spec的所有子元素,第二个例子表示上下文节点的所有xlink属性。</P>
<P>节点测试node()表示所有类型的节点,包括元素、注释、文本、处理指令等。node()不接收参数。例如,/self::node()表示文件的根节点。</P>
<P>节点测试还可以是comment()、text()、processing-instruction(),表示节点的类型是注释、文本或处理指令,comment()和text()不接收参数,processing-instruction()可以接收参数,如/descendent::processing-instruction(
xml-stylesheet
)表示文件中以<?xml-stylesheet打头的处理指令。没有参数的processing-instruction()表示不对处理指令的名称作限制。由于注释、文本和处理指令类型的节点都不包含属性和元素,因此不能在包含这几个节点测试的位置步后,添加查找属性或者元素的位置步。如"/descendent::processing-instruction(
xml-stylesheet )/attribute::href"就不是一个合法的位置路径。
<OL>
<LI type=disc value=3><STRONG>谓词</STRONG> </LI></OL>
<P>XPointer位置步可以包括零个或多个谓词对结果集进行过滤。它将不满足谓词条件的候选节点过滤掉,关键字和节点测试首先确定候选节点的列表,谓词在其中选取最后的结果。其实,节点测试可以看成是谓词的特例。</P>
<P>一般来说,谓词应该是一个布尔表达式,它对每个候选节点计算表达式的值,如果返回值为真,则该节点满足谓词,从而被保留在结果集中,否则节点将从结果集中删除。但有时谓词的计算结果不是一个布尔表达式,返回值可能是字符串、数字、节点集合等。XPointer将返回结果转换为布尔值以确定候选节点是否满足谓词。
<UL>
<LI>非0数字转换为true,数字0和NaN转换为false,NaN是"Not a
Number"的简写,常用于表示被0除或其他非法运算的结果;
<LI>非空节点集合转换为true,否则转换为false;
<LI>非空节点片断转换为true,否则转换为false;
<LI>长度不为0的字符串(包含字符串"false")转换为true,否则转换为false; </LI></UL>
<P>XPointer中,最常用和最重要的谓词是表示位置的谓词,XPointer包括几个谓词函数position()、last()等。position()表示节点在结果列表中的序号,序号从1开始。该函数常与数字连用,中间用关系运算符=、<>、<、<=、>、>=连接,表示结果节点的位置序号与指定数字满足指定关系运算符。由于position()函数使用非常普遍,XPointer提供了一种简写形式,谓词[position()=n]可以简写为[n]。last()表示列表的节点数目,由于last()的结果是个数字,因此它也可与position()函数连用。此外,谓词中还可以包括位置步,它对谓词中的位置步进行计算,该位置步的上下文节点是当前的上下文节点。如果返回集合为空,则谓词计算结果为false,否则为true,甚至还可以用count()对位置步进行计数。下面给出几个例子:</P>
<DIV align=center>
<CENTER>
<TABLE width="80%" border=1>
<TBODY>
<TR>
<TD align=middle width="50%"><STRONG>位置步</STRONG></TD>
<TD align=middle width="50%"><STRONG>含 义</STRONG></TD></TR>
<TR>
<TD width="50%">xpointer(/descendant::sepc[postion()=2])</TD>
<TD width="50%">文件中第2个sepc元素</TD></TR>
<TR>
<TD width="50%">xpointer(id("_loc")/child::sepc[postion()>=2])</TD>
<TD width="50%">ID值为"_loc"的元素的第2个及其以后的sepc子元素。</TD></TR>
<TR>
<TD
width="50%">xpointer(id("_loc")/ancestor::*[postion()=last()])</TD>
<TD width="50%">文件中ID值为"_loc"的元素的最外层的包含元素,显然应该是文件的根元素。</TD></TR>
<TR>
<TD width="50%">xpointer(/descendant::attribute[ID="_loc"])</TD>
<TD width="50%">查找文件中所有值为_loc的ID属性。</TD></TR>
<TR>
<TD width="50%">xpointer(/descendant::customer[child::car])</TD>
<TD width="50%">文件中包含car子元素的所有customer元素。</TD></TR>
<TR>
<TD
width="50%">xpointer(/descendant::customer[count(child::car)>1])</TD>
<TD
width="50%">文件中包含两个以上car子元素的所有customer元素。</TD></TR></TBODY></TABLE></CENTER></DIV></DIV>
<P></P>
<P></P></TD></TR></TBODY></TABLE>
</center>
</div>
<P></P>
<P>
<P></P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -