开发者

XPath and Jabber-RPC

I'm trying to access the methodName element of an XML document开发者_运维问答 using XPATH in Cocoa via the NSXMLElement object.

This is the XML representation of element

<iq type='set' 
    from='requester@company-b.com/jrpc-client' 
    to='responder@company-a.com/jrpc-server' 
    id='rpc1'>
  <query xmlns='jabber:iq:rpc'>
    <methodCall>
      <methodName>examples.getStateName</methodName>
      <params>
        <param>
          <value><i4>6</i4></value>
        </param>
      </params>
    </methodCall>
  </query>
</iq>

I've tried,

NSArray *nodes = [element nodesForXPath:@"iq/query/methodCall/methodName"
                                  error:&err];

but it always returns an empty NSArray.

It works fine without the namespace.

Solution

/*[name()='iq']/*[name()='query' and namespace-uri()='jabber:iq:rpc']/*[name()='methodCall']/*[name()='methodName']


This is a FAQ about how to construct an XPath expression agains a document with default namespace. There are a lot of answers in SO.

The reason for this problem is that

  <query xmlns='jabber:iq:rpc'>

contains a default namespace and all of its descendent elements are in this namespace.

The solution is either to use location steps of the type:

 *[name()='xxx']

Then an XPath expression of the kind:

*[name()='iq']/*[name()='query']/*[name()='methodCall']/*[name()='methodName']

selects the desired nodes.

In even more complicated cases where there are multiple (nested) default namespaces, it may be necessary to use location steps of the kind:

*[name()='xxx' and namespace-uri()='theCorrectNamespace']

Or, (recommended) in the hosting language (usually possible) to register the 'jabber:iq:rpc' namespace and associate a prefix, say "x:" to it.

Then an XPath expression selecting the desired nodes will look like:

iq/x:query/x:methodCall/x:methodName

where the prefix "x:" has been associated to the registered namespace 'jabber:iq:rpc'.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜