我有一个关于XPath表达式的W3C规范(EBNF表示法)的初学者问题。该规范可在以下网址找到:http://www.w3.org/TR/xpath/。特别是我有一个关于理解以下表达式的问题:
(//attribute::name | //attribute::id)[starts-with(string(self::node()), "be") or starts-with(string(self::node()), "1")]
这似乎是一个有效的表达方式。我使用http://www.freeformatter.com/xpath-tester.html验证了以下XML文档:
<documentRoot>
<!-- Test data -->
<?xc value="2" ?>
<parent name="data" >
<child id="1" name="alpha" >Some Text</child>
<child id="2" name="beta" >
<grandchild id="2.1" name="beta-alpha" ></grandchild>
<grandchild id="2.2" name="beta-beta" ></grandchild>
</child>
<pet name="tigger" type="cat" >
<data>
<birthday month="sept" day="19" ></birthday>
<food name="Acme Cat Food" ></food>
</data>
</pet>
<pet name="Fido" type="dog" >
<description>
Large dog!
</description>
<data>
<birthday month="feb" day="3" ></birthday>
<food name="Acme Dog Food" ></food>
</data>
</pet>
<rogue name="is this real?" >
<data>
Hates dogs!
</data>
</rogue>
<child id="3" name="gamma" mark="yes" >
<!-- A comment -->
<description>
Likes all animals - especially dogs!
</description>
<grandchild id="3.1" name="gamma-alpha" >
<![CDATA[ Some non-parsable character data ]]>
</grandchild>
<grandchild id="3.2" name="gamma-beta" ></grandchild>
</child>
</parent>
</documentRoot>
这给了我以下结果:
Attribute='id="1"'
Attribute='name="beta"'
Attribute='name="beta-alpha"'
Attribute='name="beta-beta"'
我不清楚EBNF产生的哪个序列会产生上述查询。
感谢您的帮助。
答案 0 :(得分:3)
击穿:
( # group //attribute::name # the long form of //@name | # union //attribute::id # the long form of //@id ) # group end [ # predicate (think "where") starts-with( # returns true or false string( # returns a string self::node() # the long form of "." ), # ) "be" # a string literal ) # ) or # logical operator starts-with( # ...idem string( # self::node() # ), # "1" # ) # ] # end predicate
所以表达式是
的一个相当不必要的详细版本(//@name | //@id)[starts-with(., "be") or starts-with(., "1")]
选择名为"name"
或"id"
的所有属性,其值以"be"
或"1"
我不确定为什么你想要这个EBNF作品(作业,我猜),但理解表达本身可能会帮助你。
一些额外的说明:
attribute::
指定属性 axis 。child::
)。self::
轴是特殊的,它只包含相关节点。 self::node()
的缩写形式是点(.
)。这意味着如果相关节点是<foo>
节点,self::foo
将匹配它,而self::bar
则不会。{/ li>
//
是/descendant-or-self::node()/
string()
函数是多余的,因为starts-with()
无论如何都会隐式地将其参数转换为字符串。答案 1 :(得分:2)
我不知道如何正确地表示这一点,但Expr >>> FilterExpr Predicate
:
Expr > OrExpr > AndExpr > EqualityExpr > RelationalExpr > AdditiveExpr > MultiplicativeExpr > UnaryExpr > UnionExpr > PathExpr > FilterExpr > FilterExpr Predicate
给出了两部分:
(//attribute::name | //attribute::id)
[starts-with(string(self::node()), "be") or starts-with(string(self::node()), "1")]
<强> (//attribute::name | //attribute::id)
强>
FilterExpr > PrimaryExpr > '(' Expr ')'
Expr > OrExpr > AndExpr > EqualityExpr > RelationalExpr > AdditiveExpr > MultiplicativeExpr > UnaryExpr > UnionExpr > UnionExpr '|' PathExpr
为您提供//attribute::name
和//attribute::id
//attribute::name
和//attribute::id
PathExpr > LocationPath > AbsoluteLocationPath > AbbreviatedAbsoluteLocationPath > '//' RelativeLocationPath
RelativeLocationPath > Step > AxisSpecifier NodeTest Predicate*
- AxisSpecifier > AxisName '::'
- AxisName > 'attribute'
- NodeTest > NameTest
NameTest
为name
和id
谓词[starts-with(string(self::node()), "be") or starts-with(string(self::node()), "1")]
Predicate > '[' PredicateExpr ']' > Expr > OrExpr > OrExpr 'or' AndExpr
- OrExpr > AndExpr
- AndExpr > EqualityExpr > RelationalExpr > AdditiveExpr > MultiplicativeExpr > UnaryExpr > UnionExpr > PathExpr > FilterExpr > PrimaryExpr > FunctionCall > FunctionName '(' ( Argument ( ',' Argument )* )? ')'
Argument > Expr
FunctionName
为starts-with
,第一个参数为另一个FunctionCall
(string
函数),第二个参数为Literal
s(来自PathExpr > FilterExpr > PrimaryExpr
) ,“是”和“1”。
最后, self :: node()来自:
RelativeLocationPath > Step > AxisSpecifier NodeTest Predicate*
- AxisSpecifier > AxisName '::'
- AxisName > 'attribute'
- NodeTest > NodeType '(' ')'
NodeType
是'node'