解析XPath表达式了解EBNF生成规则

时间:2014-01-17 10:33:24

标签: xml parsing xpath w3c ebnf

我有一个关于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产生的哪个序列会产生上述查询。

感谢您的帮助。

2 个答案:

答案 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
  • 轴可以在任何node test之前(默认轴始终为child::)。
  • self::轴是特殊的,它只包含相关节点。 self::node()的缩写形式是点(.)。这意味着如果相关节点是<foo>节点,self::foo将匹配它,而self::bar则不会。{/ li>
  • ///descendant-or-self::node()/
  • 的简写
  • string()函数是多余的,因为starts-with()无论如何都会隐式地将其参数转换为字符串。
  • union运算符连接两个节点集。两个集合中出现的节点不会在结果中重复。
  • 谓词应用于节点集中的每个节点,有效地过滤它。

答案 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

NameTestnameid

谓词[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

FunctionNamestarts-with,第一个参数为另一个FunctionCallstring函数),第二个参数为Literal s(来自PathExpr > FilterExpr > PrimaryExpr) ,“是”和“1”。

最后, self :: node()来自:

RelativeLocationPath > Step > AxisSpecifier NodeTest Predicate*
    - AxisSpecifier > AxisName '::'
        - AxisName > 'attribute'
    - NodeTest > NodeType '(' ')'

NodeType是'node'