Préserver certains noeuds lors de l'utilisation LINQ to XML
-
27-09-2019 - |
Question
J'éprouve des difficultés à préserver certains nœuds (dans ce cas <b>
) lorsque l'analyse XML avec LINQ to XML. Je prends un premier noeud avec la requête LINQ suivante ...
IEnumerable<XElement> node = from el in _theData.Descendants("msDict") select el;
Ce qui renvoie le code XML suivant (comme la première XElement
) ...
<msDict lexid="m_en_us0000002.001" type="core">
<df>(preceding a numeral) <b>pound</b> or <b>pounds</b> (of money)
<genpunc tag="df">.</genpunc></df>
</msDict>
Je collectionne ensuite le contenu avec le code suivant ...
StringBuilder output = new StringBuilder();
foreach (XElement elem in node)
{
output.append(elem.Value);
}
Voici le point de rupture. Tous les noeuds XML sont dépouillés, mais je veux préserver toutes les instances de <b>
. J'attends pour obtenir ce qui suit en sortie ...
(preceding a numeral) <b>pound</b> or <b>pounds</b> (of money).
Note: Je sais que cela est une opération simple XSLT, mais je voudrais savoir s'il y a un moyen facile de le faire en utilisant LINQ to XML.
La solution
Dans la catégorie « cela fonctionne, mais il est en désordre et je ne peux pas croire que je dois recourir à cette »:
StringBuilder output = new StringBuilder();
foreach (XElement elem in node)
{
output.append(string.Join("", elem.Nodes().Select(n => n.ToString()).ToArray()));
}
Personnellement, je pense que cela crie une méthode d'extension sur XElement ...
Mise à jour: Si vous voulez exclure toutes les balises élément sauf vous aurez besoin d'utiliser une méthode récursive pour les valeurs de nœud de retour.
Voici votre corps principal de la méthode:
StringBuilder output = new StringBuilder();
foreach (XElement elem in node)
{
output.Append(stripTags(elem));
}
Et voici StripTags:
private static string stripTags(XNode node)
{
if (node is XElement && !((XElement)node).Name.ToString().Equals("b", StringComparison.InvariantCultureIgnoreCase))
{
return string.Join(string.Empty, ((XElement)node).Nodes().Select(n => stripTags(n)).ToArray());
}
else
{
return node.ToString();
}
}
Donc, la vraie réponse est que non, il n'y a pas un moyen facile de le faire en utilisant LINQ to XML, mais il y a a chemin ...