La meilleure façon d'obtenir InnerXml d'un XElement ?

Quel est le meilleur moyen d'obtenir le contenu de l'élément mixte body dans le code ci-dessous ? L'élément peut contenir du XHTML ou du texte, mais je veux juste son contenu sous forme de chaîne. Le type XmlElement a la propriété InnerXml qui est exactement ce que je recherche.

Le code tel qu'il est écrit presque fait ce que je veux, mais inclut l'élément <body>...</body> environnant, ce que je ne fais pas veux.

XDocument doc = XDocument.Load(new StreamReader(s));
var templates = from t in doc.Descendants('template')
                where t.Attribute('name').Value == templateName
                select new
                {
                   Subject = t.Element('subject').Value,
                   Body = t.Element('body').ToString()
                };
请先 登录 后评论

5 réponses

Greg Hurlman

Est-il possible d'utiliser les objets d'espace de noms System.Xml pour faire le travail ici au lieu d'utiliser LINQ ? Comme vous l'avez déjà mentionné, XmlNode.InnerXml est exactement ce dont vous avez besoin.

请先 登录 后评论
Mike Powell

@Greg : Il semble que vous ayez modifié votre réponse pour en faire une réponse complètement différente. À quoi ma réponse est oui, je pourrais le faire en utilisant System.Xml mais j'espérais me mouiller les pieds avec LINQ to XML.

Je laisserai ma réponse d'origine ci-dessous au cas où quelqu'un d'autre se demanderait pourquoi je ne peux pas simplement utiliser la propriété .Value de XElement pour obtenir ce dont j'ai besoin :

@Greg : la propriété Value concatène tout le contenu textuel de tous les nœuds enfants. Donc, si l'élément body ne contient que du texte, cela fonctionne, mais s'il contient du XHTML, j'obtiens tout le texte concaténé mais aucune des balises.

请先 登录 后评论
Instance Hunter

Je pense que c'est une bien meilleure méthode (en VB, ça ne devrait pas être difficile à traduire) :

Étant donné un XElement x :

Dim xReader = x.CreateReader
xReader.MoveToContent
xReader.ReadInnerXml
请先 登录 后评论
Ayyash

vous savez ? la meilleure chose à faire est de revenir à CDATA :( je regarde des solutions ici mais je pense que CDATA est de loin le plus simple et le moins cher, pas le plus pratique à développer avec

请先 登录 后评论
Martin R-L

Personnellement, j'ai fini par écrire une méthode d'extension InnerXml en utilisant la méthode Aggregate :

public static string InnerXml(this XElement thiz)
{
   return thiz.Nodes().Aggregate( string.Empty, ( element, node ) => element += node.ToString() );
}

Mon code client est alors aussi concis qu'il le serait avec l'ancien espace de noms System.Xml :

var innerXml = myXElement.InnerXml();
请先 登录 后评论