2012-03-01 1 views
0

J'ai un document XML que j'analyse et qui ne suit aucun type de schéma fixe. J'ai besoin d'analyser des valeurs en faisant quelque chose comme ceci:Analyse XML à tolérance de pannes

invoiceDetail.PartNO = invoiceLine.Element(ns + "Item").Element(ns + "ItemID").Element(ns + "ID").Value; 

Dans cet exemple, invoiceLine est de type XElement. Le problème est que certains nœuds n'existent pas toujours et dans ce cas, je préférerais renvoyer une valeur nulle ou vide au lieu de renvoyer une erreur. Y at-il un moyen de le faire actuellement ou devrais-je simplement faire une fonction spéciale moi-même qui prend un espace de noms et une liste de noms d'éléments pour tenter d'analyser?

+0

S'il ne suit aucune norme, il ne peut pas être XML (ce qui est un standard). – Oded

+0

@Oded - Alors comment l'appelleriez-vous? Il suit la norme d'avoir des étiquettes de fermeture pour chaque étiquette d'ouverture. Le problème est, il réutilise les noms de balises à plusieurs niveaux et répète les balises avec des noms différents au même niveau. Il a aussi des étiquettes qui peuvent apparaître ou non dans différents documents du même type. –

+0

Dire qu'il ne suit aucune norme mais que c'est XML est trompeur. Si c'est du XML bien formé, il est bien formé en XML et suit cette norme. Si vous voulez dire qu'il n'a pas de schéma fixe et qu'il ne peut pas être validé par rapport à un schéma, c'est différent. – Oded

Répondre

2

XLINQ le fait déjà.
.Element() renverra null s'il n'y a aucun élément portant ce nom.

Pour éviter les contrôles répétitifs null, utilisez .Elements() à la place:

invoiceDetail.PartNO = (string) 
    invoiceLine.Elements(ns + "Item") 
       .Elements(ns + "ItemID") 
       .Elements(ns + "ID") 
       .SingleOrDefault(); 

Chaque appel Elements() renverra une IEnumerable<XElement>. S'il n'y a aucun élément correspondant, il renverra une séquence vide, et le reste du code fonctionnera toujours.

.SingleOrDefault() convertira la séquence finale en un seul élément ou null.
La distribution (string) appelle une conversion explicite personnalisée qui doit renvoyer null si l'élément était null. Vous pouvez également convertir directement des types de valeurs de base.

+0

Juste mais si je dois aller 3 Elements profonds, je dois vérifier chaque résultat de .Element() avant que je passe à la prochaine et enfin, je dois vérifier si le dernier .Element() est nul avant d'obtenir mon valeur ou je me retrouve avec une erreur. –

+1

@RandomBen: Appelez '.Elements()' (pluriel) à la place. De cette façon, vous obtiendrez une collection vide au lieu de 'null'. – SLaks

+1

Est-ce une option pour utiliser invoiceLine.Descendants ("ID"). Il renverrait tous les éléments "ID", sans tenir compte de la structure. –

Questions connexes