2011-12-05 37 views
0

可以说我有一个XML结构是这样的:AND和ORs与XPath。查询只在一个节点的孩子,检查所有的节点为孩子匹配查询

<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”和节点的文本值。

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

现在我想使用XPath来验证是否之一:

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

我怎么会写这样一个XPath字符串? “val1”必须与“value1”在XML中处于同一级别。 “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") 

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

如果有匹配,我可以返回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"] ] ] 

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

回答

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')] 
+0

看起来像是一个工作模式。谢谢:)我不知道如何限制一个节点的子节点内的测试,但* [测试]似乎这样做。 – Wolf5

+0

如果我想做这个检查而不关心大写或小写的情况,你会如何改写? – Wolf5

+0

XPath 1.0的设计不好,你必须翻译字符。例如'translate(* [@ id ='myid'],'ABCDEFG ...','abcdefg ...')='value1'。使用XPath 2.0,而不是翻译,您可以使用小写函数。 –