francis

Fun with XPath: Combining many fields in a query.

posted Wednesday, 22 February 2006
This is one of those things that are so obvious I felt like kicking myself when I realised how to do it.

First, some XML:
<?xml version="1.0" standalone="yes"?> 
<styling_rules >
<rule column="NAME" >
<features style="MAG:C.WASSNAME.CHOCOLATE"> NAME='T BAR BOO' </features>
<label column="NAME" style="MAG:T.STREET NAME">1</label>
</rule>
<rule column="NAME" >
<features style="MAG:C.WASSNAME.CORAL"> NAME='UP A CREEK' </features>
<label column="NAME" style="MAG:T.STREET NAME">1</label>
</rule>
<rule column="NAME" >
<features style="MAG:C.WASSNAME.CORNFLOWERBLUE"> NAME='UNHAPPY VALLEY' </features>
<label column="NAME" style="MAG:T.STREET NAME">1</label>
</rule>
</styling_rules>
This has been anonomised for the purposes of this discussion. The tool that uses the data flattens the two elements inside the rule element out so fine. I needed an XPath that would get me a particular rule node so I can manipulate it.

I put my SQL head on and looked for two sets that I could combine:
xPath = "/styling_rules/rule[@column='NAME']/features[@style='MAG:C.WASSNAME.CORNFLOWERBLUE' " + 
" and /styling_rules/rule[@column='NAME']/features/[text() = \" NAME='UNHAPPY VALLEY' \" " ;

Nah, don't even go there, it doesn't choke but it doesn't do anything. Instead think directory path and the *nix find command comined together:
xPath = "/styling_rules/rule[@column='NAME']/features[@style='MAG:C.WASSNAME.CORNFLOWERBLUE' " + 
" and ./text() = \" NAME='UNHAPPY VALLEY' \" ]/parent::" ;
This should get me the whole node and I can then update the elements in it to my heart's content.

links: digg this    del.icio.us    technorati