Comment obtenir la valeur de XElement et non la valeur de tous les enfants nœuds?

StackOverflow https://stackoverflow.com/questions/4251215

  •  27-09-2019
  •  | 
  •  

Question

xml Exemple:

<parent>
<child>test1</child>
<child>test2</child>
</parent>

Si je cherche parent.Value où parent est XElement, je reçois "test1test2". Ce que je me attends est « ». (Car il n'y a pas de texte / valeur.

Quels sont les biens de XElement dois-je chercher?

Était-ce utile?

La solution

Lorsque la recherche de données texte dans l'élément <parent> vous devriez chercher nœuds enfants qui ont propriétés de NodeType égal à XmlNodeType.Text . Ces nœuds seront de type XText . L'exemple suivant illustre ceci:

var p = XElement
    .Parse("<parent>Hello<child>test1</child>World<child>test2</child>!</parent>");

var textNodes = from c in p.Nodes()
                where c.NodeType == XmlNodeType.Text
                select (XText)c;

foreach (var t in textNodes)
{
    Console.WriteLine(t.Value);
}

Mise à jour: si vous voulez simplement est le premier nœud de texte, le cas échéant, voici un exemple en utilisant les appels de méthode LINQ au lieu de la syntaxe compréhension requête:

var firstTextNode = p.Nodes().OfType<XText>().FirstOrDefault();
if (firstTextNode != null)
{
    var textValue = firstTextNode.Value;
    ...do something interesting with the value
}

Remarque: en utilisant First() ou FirstOrDefault() sera plus performant que Count() > 0 dans ce scénario. Count toujours toute énumère collection en FirstOrDefault() n'énumérer jusqu'à ce qu'une correspondance soit trouvée.

Autres conseils

Vous pourriez concaténer la valeur de tous les nœuds XText dans parent:

XElement parent = XElement.Parse(
    @"<parent>Hello<child>test1</child>World<child>test2</child>!</parent>");

string result = string.Concat(
    parent.Nodes().OfType<XText>().Select(t => t.Value));

// result  ==  "HelloWorld!"

A titre de comparaison:

// parent.Value  ==  "Hellotest1Worldtest2!"

// (parent.HasElements ? "" : parent.Value)  ==  ""

Il est étonnant qu'un codeur quelque part à Microsoft pense que le retour de toutes les valeurs de texte comme une chaîne concaténée et non délimité serait utile. Heureusement, un autre développeur MS a écrit une extension XElement pour retourner ce qu'ils appellent le « Shallow Valeur » du noeud texte ici . Pour ceux qui sont les chocottes de cliquer sur les liens, la fonction est ci-dessous ...

    public static string ShallowValue(this XElement element)
    {
        return element
               .Nodes()
               .OfType<XText>()
               .Aggregate(new StringBuilder(),
                          (s, c) => s.Append(c),
                          s => s.ToString());
    }

Et vous appelez ça comme ça, parce qu'il vous donne tous les espaces trop (ou, à bien y penser, vous pouvez couper dans l'extension, peu importe)

// element is a var in your code of type XElement ...
string myTextContent = element.ShallowValue().Trim();

msdn dit:

  

Une chaîne qui contient tout le contenu du texte de cet élément. S'il y a des nœuds de texte multiples, ils seront concaténés.

Ainsi, le comportement est à prévoir.

Vous pourriez résoudre votre problème en faisant:

string textContent = parent.HasElements ? "" : parent.Value;
// Create the XElement
XElement parent = XElement.Parse(
    @"<parent>Hello<child>test1</child>World<child>test2</child>!</parent>");

// Make a copy
XElement temp=new XElement(parent);

// remove all elements but root
temp.RemoveNodes();

// now, do something with temp.value, e.g.
Console.WriteLine(temp.value);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top