2010-10-26 4 views
1

J'essaie d'accéder à l'élément methodName d'un document XML en utilisant XPATH dans Cocoa via l'objet NSXMLElement.XPath et Jabber-RPC

C'est la représentation XML de element

<iq type='set' 
    from='[email protected]/jrpc-client' 
    to='[email protected]/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> 

J'ai essayé,

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

mais il retourne toujours un NSArray vide.

Cela fonctionne très bien sans l'espace de noms.

Solution

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

Bonne question, +1. Voir ma réponse pour une explication détaillée et deux solutions alternatives. –

Répondre

1

Ceci est une FAQ sur la façon de construire une expression XPath Agains un document avec espace de noms par défaut. Il y a beaucoup de réponses dans SO.

La raison de ce problème est que

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

contient un espace de noms par défaut et tous ses éléments descendants se trouvent dans cet espace de noms.

La solution est soit d'utiliser des mesures de localisation du type:

*[name()='xxx'] 

Ensuite, une expression XPath du type:

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

sélectionne les noeuds souhaités.

Dans des cas encore plus compliquées où il y a plusieurs (imbriqués) les espaces de noms par défaut, il peut être nécessaire d'utiliser des mesures de localisation du genre:

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

Ou, (recommandé) dans la langue d'hébergement (généralement possible) pour enregistrer l'espace de noms 'jabber:iq:rpc' et associer un préfixe, par exemple "x:".

Puis une expression XPath sélectionnant les nœuds souhaités ressemblera:

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

où le préfixe "x:" a été associé à l'espace de noms enregistré 'jabber:iq:rpc'.

+0

J'ai vraiment * comme * recommandé, mais je ne trouve nulle part comment enregistrer un espace de nom dans le cacao. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/NSXML_Concepts/NSXML.html –

+0

@Kendall: Je ne connais rien à Cocoa. Marquez votre question "xpathengines" et "cacao" et quelqu'un pourrait arriver à fournir cette information. –

+0

@Dimitre Pourriez-vous me donner un exemple d'une autre langue? Où devrais-je enregistrer l'espace de noms? Sur l'objet Xpath, l'élément XML? –