2011-03-05 6 views
0

J'essaie de trouver une façon facile et lisse de faire la demande suivante.Analyser les balises optionnelles en C#

J'ai un message XML avec cet arrangement:

<persons> 
    <person> 
     <firstName>Mike</firstName> 
     <middleName>K.</middleName> 
     <lastName>Kelly</lastName> 
    </person> 
    <person> 
     <firstName>Steve</firstName> 
     <lastName>David</lastName> 
    </person> 
    <person> 
     <firstName>Laura</firstName> 
     <middleName>X.</middleName> 
     <lastName>Xavier</lastName> 
    </person> 
    </persons> 

Je veux analyser ce XML en utilisant des expressions XPath.

persons/person/firstName 
persons/person/middleName 
persons/person/lastName 

Mon objectif est de stocker des valeurs d'étiquette prenom, middleName et nom comme celui-ci dans une liste d'objets à cordes comme ceci:

firstNameList[0] = "Mike"; 
firstNameList[1] = "Steve"; 
firstNameList[2] = "Laura"; 

middleNameList[0] = "K."; 
middleNameList[1] = null; 
middleNameList[2] = "X."; 

lastNameList[0] = "Kelly"; 
lastNameList[1] = "David"; 
lastNameList[2] = "Xavier"; 

Dans mon code C#, je fais ceci:

XmlNodeList firstNameNodeList = xmlDoc.SelectNodes("persons/person/firstName", nsmgr); 
XmlNodeList middleNameNodeList = xmlDoc.SelectNodes("persons/person/middleName", nsmgr); 
XmlNodeList lastNameNodeList = xmlDoc.SelectNodes("persons/person/lastName", nsmgr); 

Le problème avec ce code est que pour le deuxième prénom, je ne l'ai pas pour la deuxième personne dans ma liste XML. Donc le nomNoeudNomDeListe renvoie 2 valeurs (K. et X.) mais je ne saurais pas si le deuxième prénom de la première ou deuxième ou troisième personne est manquant.

J'espérais que l'API SelectNodes() fournirait un itération ou un index ID en tant qu'élément répétitif ayant une valeur donnée.

S'il vous plaît me suggérer un moyen le plus facile de réaliser ce dont j'avais besoin? Merci beaucoup pour votre aide, JK

+1

pouvez-vous avoir pour personne sans prénom? –

+0

@StackOverflowException, c'est une bonne idée. Dans ce cas, SelectNodes() renverrait-il 3 valeurs dans cet exemple? K., null et X.? J'ai besoin de l'expérimenter. – JKK

+0

oui. le second nomMoyen ne sera pas nul mais le 'InnerXml' de' XmlNodeList' serait vide. Voir ma réponse :) –

Répondre

1

Au lieu d'obtenir une liste de noms, essayez d'obtenir une liste de person s, puis parcourir la liste et obtenir leurs noms.

0

Vous avez juste à itérer sur persons/person et de traiter chacun individuellement - cela fonctionnerait:

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.Load(@"test.xml"); 
var persons = xmlDoc.SelectNodes("persons/person"); 
foreach (XmlNode person in persons) 
{ 
    string firstName = person.SelectSingleNode("firstName").InnerText; 
    string middleName = (person.SelectSingleNode("middleName") != null) 
         ? person.SelectSingleNode("middleName").InnerText 
         : null; 
    string lastName = person.SelectSingleNode("lastName").InnerText; 
} 
2

Comment cela?

foreach (Node person in xmlDoc.SelectNodes("persons/person", nsmgr)) 
{ 
    firstNameNodeList.Add(person.SelectSingleNode("firstName", nsmgr)); 
    middleNameNodeList.Add(person.SelectSingleNode("middleName", nsmgr)); 
    lastNameNodeList.Add(person.SelectSingleNode("lastName", nsmgr)); 
} 
+0

Je viens de donner l'exemple XML pour expliquer le point cependant dans mon système réel, j'obtiendrais un élément de répétition complexe avec xpaths prédéfini. Donc, je ne connais pas les noms de balises individuelles, seulement l'expression XPath. Je veux aller aussi générique que possible. D'autres idées? – JKK

+0

@JKK: il n'y a aucune garantie que les nodelists sont commandés. Vous ne pouvez pas supposer que, disons, les 3èmes éléments de tous les nodelists appartiennent à la même "personne". Donc, la réponse ci-dessus par Jollymorphic est la voie à suivre. – muratgu

0

Essayez

<persons> 
    <person> 
     <firstName>Mike</firstName> 
     <middleName>K.</middleName> 
     <lastName>Kelly</lastName> 
    </person> 
    <person> 
     <firstName>Steve</firstName> 
     <middleName /> 
     <lastName>David</lastName> 
    </person> 
    <person> 
     <firstName>Laura</firstName> 
     <middleName>X.</middleName> 
     <lastName>Xavier</lastName> 
    </person> 
    </persons> 

<person> 
    <firstName>Steve</firstName> 
    <middleName /> 
    <lastName>David</lastName> 
</person> 

cela devrait retourner "K", "", "X" pour InnnerText

Questions connexes