Supprimer vide balises XML
Je suis à la recherche d'une bonne approche qui permet de supprimer les balises vides à partir de XML de manière efficace. Que recommandez-vous? Regex? XDocument? XmlTextReader?
Par exemple,
const string original =
@"<?xml version=""1.0"" encoding=""utf-16""?>
<pet>
<cat>Tom</cat>
<pig />
<dog>Puppy</dog>
<snake></snake>
<elephant>
<africanElephant></africanElephant>
<asianElephant>Biggy</asianElephant>
</elephant>
<tiger>
<tigerWoods></tigerWoods>
<americanTiger></americanTiger>
</tiger>
</pet>";
Peut devenir:
const string expected =
@"<?xml version=""1.0"" encoding=""utf-16""?>
<pet>
<cat>Tom</cat>
<dog>Puppy</dog>
<elephant>
<asianElephant>Biggy</asianElephant>
</elephant>
</pet>";
argh! pas de regex!
J'ai fait un simple perfermance test hier, le XDocument est beaucoup mieux que les regex en termes de performances, je n'ai pas encore travaillé sur la façon de la mettre en œuvre à l'aide de la classe XmlTextReader, en termes de complexité, de XDocument est assez bon pour résoudre mon exigence, donc, je vais, pour XDocument, Merci à tous de votre aide!
cela peut vous aider stackoverflow.com/questions/14509188/...
J'ai fait un simple perfermance test hier, le XDocument est beaucoup mieux que les regex en termes de performances, je n'ai pas encore travaillé sur la façon de la mettre en œuvre à l'aide de la classe XmlTextReader, en termes de complexité, de XDocument est assez bon pour résoudre mon exigence, donc, je vais, pour XDocument, Merci à tous de votre aide!
cela peut vous aider stackoverflow.com/questions/14509188/...
OriginalL'auteur Ming | 2011-09-06
Vous devez vous connecter pour publier un commentaire.
Chargement de votre original dans un
XDocument
et en utilisant le code suivant donne la sortie souhaitée:<asdf attr="val" />
serait supprimé, ce qui peut ne pas être souhaitable. J'ai fourni une autre réponse d'après ce de les compléter.vieille question, mais permet d'ajouter des mises à jour et/ou de meilleures réponses. Vous pourriez avoir également mis à jour ma réponse, si vous l'auriez souhaité. De toute façon je upvoted votre réponse.
Ce que cette ligne de document.Les Descendants() va faire?
Ils ont tendance à expliquer bien en la documentation
OriginalL'auteur
C'est censé être une amélioration sur la accepté de répondre à gérer les attributs:
L'idée ici est de vérifier que tous les attributs d'un élément sont également vides avant de les retirer. , Il est vrai aussi que vide descendants peuvent avoir des attributs vides. J'ai inséré un troisième condition pour vérifier que l'élément a tous les attributs vides parmi ses descendants. Considérant le document suivant avec node8 ajouté:
Ce serait:
L'original et l'amélioration de réponse à cette question serait de perdre la
node2
etnode6
etnode8
nœuds. La vérification dee.IsEmpty
si vous souhaitez uniquement extraire les nœuds comme<node />
, mais c'est redunant si vous allez pour les deux<node />
et<node></node>
. Si vous devez également supprimer des attributs vides, vous pourriez faire ceci:qui vous donnerait:
OriginalL'auteur
Comme toujours, cela dépend de vos exigences.
Savez-vous comment l'étiquette vide affiche? (par exemple,
<pig />
,<pig></pig>
, etc.) En général, je ne recommande pas d'utiliser des Expressions Régulières (ils sont vraiment utiles, mais en même temps, ils sont le mal). Aussi compte d'unestring.Replace
approche semble être problématique, à moins que votre XML n'a pas une certaine structure.Enfin, je vous conseille d'utiliser un analyseur XML approche (assurez-vous que votre code est valide XML).
ForEach
etRemove
- la suppression de la méthode agit sur tous les éléments de l'interface IEnumerable.Repéré le "erreur". Édité, merci 🙂
+1 pour le fait de fournir une solution plus tôt que l'on a accepté la réponse, qui est juste un peu plus élégante version de celui-ci.
OriginalL'auteur
Tout ce que vous utilisez devront passer par le fichier, une fois au moins. Si c'est juste un nom de balise que vous savez alors regex est ton ami sinon utiliser une pile d'approche. Commencez avec une balise parent et si elle a une sous-balise de le placer dans la pile. Si vous trouvez une balise vide le supprimer une fois que vous avez traversé des balises enfants et arrivé à la fin de la balise de ce que vous avez sur le dessus de la pile, puis de la pop et de vérifier ainsi. Si son vide effacer ainsi. De cette façon, vous pouvez supprimer toutes les balises vides y compris les balises vides enfants.
Si vous êtes après un reg ex expression utiliser cette
OriginalL'auteur
XDocument
est probablement la plus simple à mettre en œuvre, et de donner une performance adéquate si vous savez que vos documents sont de taille raisonnable.XmlTextReader
sera plus rapide et utilise moins de mémoire que XDocument lors du traitement de documents de très grande taille.Regex est meilleur pour la manipulation de texte, plutôt que d'XML. Il pourrait ne pas traiter tous les cas de bord que vous souhaitez (par exemple, une balise à l'intérieur d'une section CDATA; une étiquette avec un attribut xmlns), donc c'est probablement pas une bonne idée pour une mise en œuvre générale, mais peuvent être adaptées en fonction de combien vous avez de contrôle de l'entrée XML.
jetez un oeil à l'article MSDN suivant, qui décrit comment la chaîne d'un objet XmlReader à un XmlWriter, une technique qui permet de filtrer les données XML dans la façon dont vous le souhaitez: msdn.microsoft.com/en-us/library/aa302289.aspx
OriginalL'auteur
XmlTextReader est préférable si nous parlons de la performance (il fournit rapide, avant uniquement l'accès à XML). Vous pouvez déterminer si la balise est vide à l'aide de
XmlReader.IsEmptyElement
propriété.XDocument approche qui produit de la sortie souhaitée:
Vous pouvez implémenter la même logique que j'ai fourni pour XDocument.
OriginalL'auteur