2010-08-19 27 views
1

J'utilise C# et .NET 2.0.Comment utiliser la fonction translate dans un prédicat d'un argument XPath vers XmlDocument.SelectNodes?

Étant donné le code XML ci-dessous, je voudrais obtenir un XMLNodeList de <user> nœuds où le <role> est "admin".

<users> 
    <user> 
     <name>John Doe</name> 
     <roles> 
      <role>superadmin</role> 
      <role>admin</role> 
     </roles> 
    </user> 
    <user> 
     <name>Jane Doe</name> 
     <roles> 
      <role>superadmin</role> 
      <role>admin</role> 
     </roles> 
    </user> 
    <user> 
     <name>Rob Doe</name> 
     <roles> 
      <role>support</role> 
     </roles> 
    </user> 
</users> 

Supposons roleName = "admin". Cela fonctionne, mais est sensible à la casse.

userNodesForRole = _document.SelectNodes("//users/user[roles[role='" + roleName + "']]"); 

Je veux le faire sans tenir compte de la casse. Je sais que je ne peux pas utiliser la fonction matches parce que .NET 2.0 (et peut-être plus élevé?) Ne supporte pas XPath 2.0. J'ai donc fait ceci:

// abc...xyz is the string literal of the entire alphabet, of course 
userNodesForRole = _document.SelectNodes("//users/user[roles[translate(role,'abc..xyz','ABC...XYZ')='" + roleName.ToUpper() + "']]", _xmlNamespaceManager); 

Cependant, je ne récupère aucun noeud. Quelqu'un peut-il me dire ce que je me trompe?

+0

BTW, C# n'est pas vraiment pertinent pour votre question. C'est une question .NET 2.0, et vous êtes en train de programmer en C#. –

+0

Que se passe-t-il lorsque vous essayez d'utiliser votre code avec l'appel de 'translate'? Ça a l'air ok sur la surface. – Jacob

Répondre

1

_document.SelectNodes ("// utilisateurs/rôles utilisateur [[Traduire (rôle, 'abc..xyz', 'ABC ... XYZ') = '" + roleName.ToUpper() + " ']] ", _xmlNamespaceManager);

Cette évalue une expression XPath comme ce qui suit:

//users/user 
      [roles 
      [translate(role, 
         'abcdefghijklmnopqrstuvxyz', 
         'ABCDEFGHIJKLMNOPQRSTUVXYZ' 
         ) 
      = 
       'ADMIN' 
       ] 
      ] 

et l'expression XPath ci-dessus lors de l'évaluation sur le document XML fourni:

<users> 
    <user> 
     <name>John Doe</name> 
     <roles> 
      <role>admin</role> 
     </roles> 
    </user> 
    <user> 
     <name>Jane Doe</name> 
     <roles> 
      <role>admin</role> 
     </roles> 
    </user> 
    <user> 
     <name>Rob Doe</name> 
     <roles> 
      <role>support</role> 
     </roles> 
    </user> 
</users> 

sélectionne les nœuds suivants:

<user> 
    <name>John Doe</name> 
    <roles> 
     <role>admin</role> 
    </roles> 
</user> 

<user> 
    <name>Jane Doe</name> 
    <roles> 
     <role>admin</role> 
    </roles> 
</user> 

L'expression XPath ne sélectionne pas les éléments recherchés s'il y a un élément roles qui a plus d'un role enfant et un élément <role>admin</role> n'est pas le premier enfant role de son parent.

Une expression XPath qui sélectionne les éléments souhaités même dans ce cas est;

//users/user 
      [roles/role 
      [translate(., 
         'abcdefghijklmnopqrstuvxyz', 
         'ABCDEFGHIJKLMNOPQRSTUVXYZ' 
         ) 
      = 
       'ADMIN' 
       ] 
      ] 

Il peut y avoir une variété de raisons pour lesquelles la première expression soulève une exception ou ne sélectionne pas les nœuds recherchés. Pour connaître la raison exacte, imprimez l'expression XPath construite et fournissez-la ici.

Mise à jour: @ck a fourni son maintenant réel document XML et en effet, dans le document XML réel les role enfants (<role>admin</role> éléments) arenot le premier enfant role de leurs parents.

Donc, ma conjecture et l'explication était correct.

+0

Merci. Vous frappez le clou sur la tête.J'ai édité la question pour refléter le XML réel que j'essayais d'analyser de plus près. J'ai cependant une question similaire. Je l'afficherai séparément. –

+0

@ck: Vous êtes les bienvenus. –