Je recherche la solution propre, élégante et intelligente pour supprimer les espaces de noms de tous les éléments XML? Comment cela fonctionnerait-il?
Interface définie:
public interface IXMLUtils
{
string RemoveAllNamespaces(string xmlDocument);
}
Exemple de XML pour supprimer NS:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfInserts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<insert>
<offer xmlns="http://schema.peters.com/doc_353/1/Types">0174587</offer>
<type2 xmlns="http://schema.peters.com/doc_353/1/Types">014717</type2>
<supplier xmlns="http://schema.peters.com/doc_353/1/Types">019172</supplier>
<id_frame xmlns="http://schema.peters.com/doc_353/1/Types" />
<type3 xmlns="http://schema.peters.com/doc_353/1/Types">
<type2 />
<main>false</main>
</type3>
<status xmlns="http://schema.peters.com/doc_353/1/Types">Some state</status>
</insert>
</ArrayOfInserts>
Après avoir appelé RemoveAllNamespaces (xmlWithLotOfNs), nous devrions obtenir:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfInserts>
<insert>
<offer >0174587</offer>
<type2 >014717</type2>
<supplier >019172</supplier>
<id_frame />
<type3 >
<type2 />
<main>false</main>
</type3>
<status >Some state</status>
</insert>
</ArrayOfInserts>
Le langage de solution préféré est C # sur .NET 3.5 SP1.
Réponses:
Eh bien, voici la réponse finale. J'ai utilisé une excellente idée de Jimmy (qui malheureusement n'est pas complète en soi) et une fonction de récursivité complète pour fonctionner correctement.
Basé sur l'interface:
Je représente ici la solution C # finale propre et universelle pour supprimer les espaces de noms XML:
Ça marche à 100%, mais je ne l'ai pas beaucoup testé donc ça peut ne pas couvrir certains cas particuliers ... Mais c'est une bonne base pour commencer.
la source
La réponse la plus utile étiquetée présente deux défauts:
Voici mon avis sur ceci:
Exemple de code ici .
la source
xmlns
aussi.(from a in e.Attributes().DistinctBy(x => x.Name.LocalName)
pour le caslang=""ru-ru"" xml:lang=""ru-ru""
la réponse obligatoire via LINQ:
la source
Cela fera l'affaire :-)
la source
Reprenez-le à nouveau, en C # - ligne ajoutée pour copier les attributs:
la source
La réponse obligatoire avec XSLT:
la source
Et c'est la solution parfaite qui supprimera également les éléments XSI. (Si vous supprimez les xmlns et ne supprimez pas XSI, .Net vous crie dessus ...)
la source
Regex.Replace(xmlStr, @"<(/?)([^>\s:]+):([^>]+)>", "<$1$3>")
Je sais que cette question est censée être résolue, mais je n'étais pas totalement satisfaite de la façon dont elle a été mise en œuvre. J'ai trouvé une autre source ici sur les blogs MSDN qui a une
XmlTextWriter
classe remplacée qui supprime les espaces de noms. Je l'ai un peu modifié pour obtenir d'autres éléments que je souhaitais, tels que le joli formatage et la préservation de l'élément racine. Voici ce que j'ai dans mon projet en ce moment.http://blogs.msdn.com/b/kaevans/archive/2004/08/02/206432.aspx
Classe
Usage
la source
C'est une solution basée sur la réponse acceptée de Peter Stegnar.
Je l'ai utilisé, mais (comme andygjp et John Saunders l'ont fait remarquer) son code ignore les attributs .
J'avais aussi besoin de m'occuper des attributs, j'ai donc adapté son code. La version d'Andy était Visual Basic, c'est toujours c #.
Je sais que ça fait un moment, mais peut-être que ça fera gagner du temps à quelqu'un un jour.
la source
J'ai vraiment aimé où Dexter va là-haut, alors je l'ai traduit en une méthode d'extension «fluide»:
L'approche «fluide» me permet de faire ceci:
la source
Vous pouvez le faire en utilisant Linq:
la source
Légèrement modifié la réponse de Peter, cela fonctionnerait bien pour l'attribut également, y compris la suppression de l'espace de noms et du préfixe. Un peu désolé pour le code semble un peu moche.
la source
La réponse de Jimmy et Peter a été d'une grande aide, mais ils ont en fait supprimé tous les attributs, j'ai donc fait une légère modification:
la source
Un peu tard à la fête sur celui-ci mais voici ce que j'ai utilisé récemment:
(extrait de ce fil MSDN )
Modifier Selon le commentaire ci-dessous, il semble que bien que cela supprime le préfixe d'espace de noms des nœuds, il ne supprime pas réellement l'attribut xmlns. Pour ce faire, vous devez également réinitialiser le nom de chaque nœud à son nom local (par exemple, nom moins espace de noms)
la source
Pour que les attributs fonctionnent, la boucle for pour l'ajout d'attribut doit aller après la récursivité, vous devez également vérifier si IsNamespaceDeclaration:
la source
Voici ma version VB.NET de la version C # de Dexter Legaspi
la source
Une autre solution qui prend en compte les nœuds TEXT et ELEMENT éventuellement entrelacés, par exemple:
Code:
la source
Sans recourir à une solution basée sur XSLT, si vous voulez être propre, élégant et intelligent, vous auriez besoin du support du framework, en particulier, le modèle de visiteur pourrait en faire un jeu d'enfant. Malheureusement, il n'est pas disponible ici.
Je l'ai implémenté inspiré par LINQ
ExpressionVisitor
pour avoir une structure similaire. Avec cela, vous pouvez appliquer le modèle de visiteur aux objets XML (LINQ-to-). (J'ai fait des tests limités à ce sujet mais cela fonctionne bien pour autant que je sache)ps, cette implémentation particulière utilise certaines fonctionnalités de .NET 4 pour rendre l'implémentation un peu plus facile / plus propre (utilisation des
dynamic
arguments par défaut). Il ne devrait pas être trop difficile de le rendre compatible .NET 3.5, peut-être même compatible .NET 2.0.Ensuite, pour implémenter le visiteur, en voici un généralisé qui peut changer plusieurs espaces de noms (et le préfixe utilisé).
Et une petite méthode d'aide pour lancer le bal:
Ensuite, pour supprimer un espace de noms, vous pouvez l'appeler comme ceci:
En utilisant ce visiteur, vous pouvez écrire un
INamespaceMappingManager
pour supprimer tous les espaces de noms.la source
Solution simple qui renomme réellement les éléments sur place, ne crée pas de copie, et fait un très bon travail de remplacement des attributs.
Remarque: cela ne préserve pas toujours l'ordre des attributs d'origine, mais je suis sûr que vous pouvez le modifier pour le faire assez facilement si cela est important pour vous.
Notez également que cela pourrait également lever une exception, si vous aviez des attributs XElement qui ne sont uniques qu'avec l'espace de noms, comme:
ce qui semble vraiment être un problème inhérent. Mais comme la question indiquait la sortie d'une chaîne, pas d'un XElement, dans ce cas, vous pourriez avoir une solution qui afficherait une chaîne valide qui était un XElement non valide.
J'ai aussi aimé la réponse de jocull en utilisant un XmlWriter personnalisé, mais quand je l'ai essayé, cela n'a pas fonctionné pour moi. Bien que tout semble correct, je ne pouvais pas dire si la classe XmlNoNamespaceWriter avait un effet quelconque; il ne supprimait certainement pas les espaces de noms comme je le voulais.
la source
L'ajout de my qui nettoie également le nom des nœuds qui ont des préfixes d'espace de noms:
la source
J'ai essayé les premières solutions et je n'ai pas fonctionné pour moi. Principalement le problème avec les attributs supprimés comme les autres l'ont déjà mentionné. Je dirais que mon approche est très similaire à celle de Jimmy en utilisant les constructeurs XElement qui prennent l'objet comme paramètres.
la source
ma réponse,
code basé sur la manipulation de chaînes, le plus léger,
la source
Voici Regex Replace one liner:
Voici un exemple: https://regex101.com/r/fopydN/6
Attention: il peut y avoir des cas extrêmes!
la source
La réponse de user892217 est presque correcte. Il ne se compilera pas tel quel, il nécessite donc une légère correction de l'appel récursif:
la source
Cela a fonctionné pour moi.
la source
Après avoir beaucoup cherché une solution à ce problème, cette page en particulier semblait avoir le plus de bœuf ... Cependant, rien ne me convenait parfaitement, alors j'ai pris la méthode à l'ancienne et j'ai juste analysé les choses que je voulais. J'espère que cela aide quelqu'un. (Remarque: cela supprime également le SOAP ou tout autre élément d'enveloppe similaire.)
la source
Sans recréer toute la hiérarchie des nœuds:
la source
J'ai essayé certaines des solutions, mais comme beaucoup l'ont déclaré, il y a des cas extrêmes.
Utilisé certaines des expressions régulières ci-dessus, mais est arrivé à la conclusion qu'une expression régulière en une étape n'est pas faisable.
Voici donc ma solution, regex en 2 étapes, trouver des balises, supprimer les balises dans les balises, ne pas modifier les cdata:
Pour l'instant, cela fonctionne à 100% pour moi.
la source
Voici une solution basée sur les regex à ce problème ...
la source
Je pense que c'est la réponse la plus courte (mais pour des constuctions comme, vous aurez une autre discussion, j'ai aussi une expression régulière à convertir
"<bcm:info></bcm:info>"
en "<info></info>
" mais elle n'a pas été optimisée, si quelqu'un me le demande, je la partagerai. Donc, ma solution est:la source