ServiceModel XPath Functions
One of the most versatile types of filters that the Routing Service offers is the XPathMessageFilter. Xpath is great because it gives you a full set of navigation and comparison tools, right in one filter. But let’s be honest, writing XPath by hand kinda stinks. Fortunately, XPath has the notion of functions (or shortcuts) which can be used as shorthand for longer XPath statements. As an added benefit, when you use the XPath filter inside the framework, there a whole bunch of functions that are already defined for you. Here’s the ones I’ve found particularly useful. To use these, just write them into the XPath filter, prefaced by the sm: namespace declaration.
XPath Shortcut Key |
Equivalent Functionality |
Expanded XPath Context String |
header() |
Returns a node set containing just the header node. |
(/s11:Envelope/s11:Header | /s12:Envelope/s12:Header) |
body() |
Returns a node set containing just the body node. |
(/s11:Envelope/s11:Body | /s12:Envelope/s12:Body) |
soap-uri() |
Returns the string value of the soap namespace of the message. |
namespace-uri(/s11:Envelope | /s12:Envelope) |
headers-with-actor(string) |
Returns a node set containing all header nodes with the specified role/actor. |
/s11:Envelope/s11:Header/*[@s11:actor=$string] | s12:Envelope/s12:Header/*[@s12:role=$string] |
actor(node-set) |
Returns the string value of the role/actor attribute of the first node in the node set. |
string($node-set[1][/s11:Envelope]/@s11:actor | $node-set[1][/s12:Envelope]/@s12:role) |
is-mandatory(node-set) |
Returns the Boolean value of the “mustUnderstand” attribute of the first node in the node set. |
$node-set[1][/s11:Envelope]/@s11:mustUnderstand=“1” | $node-set[1][/s12:Envelope]/@s12:mustUnderstand=“true” |
is-actor-next(node-set) |
Returns true/false depending on whether the role/actor attribute of the first node in the node set is the “next” value. |
(/s11:Envelope and sm:actor($node-set)=“https://schemas.xmlsoap.org/soap/actor/next”) | (/s12:Envelope and sm:actor($node-set)=“https://www.w3.org/2003/05/soap-envelope/role/next”) |
is-actor-ultimate-receiver(node-set) |
Returns the true/false depending on whether the role/actor attribute of the first node in the node set is the “ultimate receiver” value. |
(/s11:Envelope and sm:actor($node-set)= “”) | (/s12:Envelope and sm:actor($node-set)= “https://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver”) |
messageId() |
Returns the string value of the ws-Addressing MessageId header (string). |
string((sm:header()/wsa:MessageID/text( ))[1]) |
relatesTo() |
Returns the ws-Addressing RelatesTo headers (node-set) |
sm:header( )/wsa:RelatesTo |
replyTo() |
Returns the ws-Addressing ReplyTo header (node-set) |
(sm:header( )/wsa:ReplyTo)[1] |
from() |
Returns the ws-Addressing From header (node-set) |
(sm:header( )/wsa:From)[1] |
faultTo() |
Returns the ws-Addressing RelatesTo header (node-set) |
(sm:header( )/wsa:FaultTo)[1] |
to() |
Returns the string value of the ws-Addressing To header (string). |
string(sm:header( )/wsa:To) |
action() |
Returns string containing the string value of the ws-Addressing Action header (string). |
string((sm:header( )/wsa:Action/text())[1]) |
recipient() |
Returns the ws-Addressing recipient header (node-set) |
(sm:header( )/wsa:Recipient)[1] |
In a post below, and in several samples, I use sm:header() to quickly navigate to the header collection in order to determine if a particular header is present. With this data, you can also go ahead and start to write other XPath functions that riff off of these. Have at it!
-Matt