XPath support for MatriX

XPath support for my XMPP libraries was on my TODO list for a long time. Because agsXMPP is using its own DOM implementation I wasn’t able to use standard XPath libraries. Writing a custom XPath implementation is quite a challenge, and using System.Xml’s XPath functions would require 2 different DOMs and parsing the Xml twice, which was no option for me.

Because MatriX is using System.Xml.LinQ which has XPath support it was pretty easy to get this task done for MatriX now.

Of course you can do filtering based on powerful LinQ statements and the other filter classes in MatriX. But in many cases it’s required to build expressions dynamically on the fly. Also many programmers are familiar with XPath and prefer XPath over LinQ statements. The XPathFilter makes it also much easier to filter big complex stanzas with many nested elements.

The following example describes the usage of the XPathFilter. We setup a filter that matches all presence stanzas from the full Jid ‘user@jabber.org/MatriX’. Because MatriX and XPath in .Net are namespace aware we have to define prefixes in the XmlNamespaceManager. Otherwise we would get no results.

e.Stanza is the complete stanza which matches the expression.
e.Result is the result of the XPath expression. This is useful when you are interested only in fragments of the complete stanza.

void XPathFilter()
	xmppClient.XPathFilter.XmlNamespaceManager.AddNamespace("JC", "jabber:client");
	xmppClient.XPathFilter.Add("/JC:presence[@from='user@jabber.org/MatriX']", XPathCallback);

void XPathCallback(object sender, XPathEventArgs e)
	Debug.WriteLine("Stanza: " + e.Stanza);
	Debug.WriteLine("Result: " + e.Result);

Here are some other XPath example expressions to filter stanzas:

  • filter all messages with the exact body of 'Hello MatriX
    /JC:message[JC:body='Hello MatriX']
  • filter all presences where the Jid starts with 'gnauck@'.
    /JC:presence[starts-with(@from ,'gnauck@')]
  • filter all messages of type=error which have a from and and a to Jid
    /JC:message[@from and @to and @type='error']

Leave a Reply

Your email address will not be published. Required fields are marked *