AND和OR与XPath。仅在节点的子节点内查询,检查与查询匹配的子节点的所有节点

时间:2011-12-05 16:15:11

标签: xml xpath

假设我有一个像这样的xml结构:

<s>
  <a>
    <b id="myid">value1</b>
    <c id="test">val1</c>
    <c id="test2">valX</c>
  </a>
  <g>
    <d id="myid">value2</d>
    <e id="test">val2</e>
  </g>
  <i id="myid">value3</i>
  <j id="test">val3</j>
</s>

请注意标记名称并不重要。只有属性“id”和节点的textvalue。

xpath查询将用于检查值是否存在,因此我可以返回整个XML。此xpath查询是在一组不同的XML字符串上完成的,这些字符串返回匹配的字符串。

现在我想使用xpath验证是否:

("myid"="value1" AND "test"="val1") OR ("myid"="value2" AND "test"="val2")

我如何将其写为XPath字符串? “val1”必须与XML中的“value1”处于同一级别。 “val2”与“value2”,“val3”和“value3”

相同

我需要以一种易于扩展的方式编写它,因为这个XPath查询将由代码生成。

生成器的输入查询将在AND / OR上带“(”和“)”。所以我需要创建一个解析器来创建XPath。

示例:

q1: ("myid"="value1" AND "test"="val1") OR ("myid"="value2" AND "test"="val2") OR 
 ("myid"="value3" AND "test"="val3")
q2: ("myid"="value1" AND "test"="val1") AND ("myid"="value2" AND "test"="val2") 
q3: "myid"="value1" AND ("test"="val1" OR "test"="valX") 

我需要的是确保在同一XML子集上执行所有@id检查的方法。所以在这个XML中,检查应该从S节点正下方的所有@ id获得匹配,或者直接在A节点下面的所有@ id匹配,或者直接在G-下面的所有@id匹配。节点。 (以及所有其他类似节点)

如果匹配完成,我可以返回XML。我不知道有多少级别,因为xml非常通用,每个值节点都有一个带有值名称的@id属性的规则。

"myid"="value1" AND "test"="val1" should return a match.
"myid"="value2" AND "test"="val2" should return a match.
"myid"="value3" AND "test"="val3" should return a match.
"myid"="value3" AND "test"="val1" should NOT return a match.
"myid"="value2" AND "test"="val3" should NOT return a match.

这可能很简单。但我还没有办法完成这项工作。谁能帮我这个。任何提示都表示赞赏。

我希望我已经明白了这一点。

如果忽略大写或小写,你会怎么写?喜欢这个?

//*[ *[@id [lower-case(.)="myid"] [lower-case(..)="value1"] ] and *[@id [lower-case(.)="test"] [lower-case(..)="val1"] ] ]

还是有更好的方法。这些值是.ToLower()'ed。

1 个答案:

答案 0 :(得分:1)

我认为你正在寻找这样的表达方式:

//*[ *[@id ='myid'] = 'value1' and *[@id ='test'] = 'val1']

结果将是具有至少两个具有以下约束的id属性的子元素的所有元素:

  • 其中一个孩子的id属性值必须等于myid,元素的值必须为value1
  • 其中一个孩子的id属性值必须等于test,元素的值必须为val1

然后,您可以根据需要添加andor。例如:

//*[ (*[@id ='myid'] = 'value1' and *[@id ='test'] = 'val1') or (*[@id ='myid'] = 'value2' and *[@id ='test'] = 'val2')]