Lets say I have an xml structure like this:
<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>
Notice the tag names are not important. Only the attribute "id" and the textvalue of the node.
The xpath query will be used to check if the values exists, so I can return the whole XML. This xpath query is done on a whole set of different XML strings returning those who match.
Now I want to use xpath to verify if either:
("myid"="value1" AND "test"="val1") OR ("myid"="value2" AND "test"="val2")
How would I write this as an XPath string? "val1" has to be on the same level in the XML as "value1". The same goes for "val2" with "value2", and "val3" and "value3"
I need to write this in a way that makes it easy to expand upon as this XPath query will be generated by code.
The input query for the generator will be on a AND/OR with "(" and ")". So I need to make a parser to create the XPath from this.
Examples:
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")
What I need is a way to make sure all the @id checks are performed on the same XML subset. So in this XML the check should either get a match from all the @id's directly below the S-node, or a match from all the @id's directly below the A-node, or a match from all @id's directly below the G-node. (and all other similar nodes)
If any match is done, I can return the XML. I do not know how many levels there are as the xml is very generic with the one rule that each value node has an @id attribute with the value name.
"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.
etc.
This might be simple. But I have not found a way to get this done. Can anyone help me with this. Any hints are appreciated.
I hope I have made this understandable.
How would you write the same where upper or lower case is ignored. Like this?
//*[ *[@id [lower-case(.)="myid"] [lower-case(..)="value1"] ] and *[@id [lower-case(.)="test"] [lower-case(..)="val1"] ] ]
or is there a better way. The values are pre .ToLower()'ed.