Comment supprimer tous les espaces de noms de XML avec C #?

Je recherche la solution propre, élégante et intelligente pour supprimer les espaces de noms de tous les éléments XML? Comment fonctionnerait cette fonction?

Interface définie:

public interface IXMLUtils { ssortingng RemoveAllNamespaces(ssortingng xmlDocument); } 

Exemple XML pour supprimer NS de:

    0174587 014717 019172    false  Some state   

Après avoir appelé RemoveAllNamespaces (xmlWithLotOfNs), nous devrions obtenir:

     0174587 014717 019172    false  Some state   

Le langage pré-ajouté de la solution est C # sur .NET 3.5 SP1.

Eh bien, voici la réponse finale. J’ai utilisé une excellente idée de Jimmy (qui n’est malheureusement pas complète) et une fonction de récursion complète pour fonctionner correctement.

Basé sur l’interface:

 ssortingng RemoveAllNamespaces(ssortingng xmlDocument); 

Je représente ici la solution finale C # propre et universelle pour supprimer les espaces de noms XML:

 //Implemented based on interface, not part of algorithm public static ssortingng RemoveAllNamespaces(ssortingng xmlDocument) { XElement xmlDocumentWithoutNs = RemoveAllNamespaces(XElement.Parse(xmlDocument)); return xmlDocumentWithoutNs.ToSsortingng(); } //Core recursion function private static XElement RemoveAllNamespaces(XElement xmlDocument) { if (!xmlDocument.HasElements) { XElement xElement = new XElement(xmlDocument.Name.LocalName); xElement.Value = xmlDocument.Value; foreach (XAtsortingbute atsortingbute in xmlDocument.Atsortingbutes()) xElement.Add(atsortingbute); return xElement; } return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el))); } 

Cela fonctionne à 100%, mais je ne l’ai pas beaucoup testé donc il ne couvre peut-être pas certains cas particuliers … Mais c’est une bonne base pour commencer.

La réponse la plus utile étiquetée a deux défauts:

  • Il ignore les atsortingbuts
  • Il ne fonctionne pas avec les éléments “mode mixte”

Voici ma version de ceci:

  public static XElement RemoveAllNamespaces(XElement e) { return new XElement(e.Name.LocalName, (from n in e.Nodes() select ((n is XElement) ? RemoveAllNamespaces(n as XElement) : n)), (e.HasAtsortingbutes) ? (from a in e.Atsortingbutes() where (!a.IsNamespaceDeclaration) select new XAtsortingbute(a.Name.LocalName, a.Value)) : null); } 

Exemple de code ici .

la réponse obligatoire en utilisant LINQ:

 static XElement ssortingpNS(XElement root) { return new XElement( root.Name.LocalName, root.HasElements ? root.Elements().Select(el => ssortingpNS(el)) : (object)root.Value ); } static void Main() { var xml = XElement.Parse(@"< ?xml version=""1.0"" encoding=""utf-16""?>   0174587 014717 019172    
false
Some state
"); Console.WriteLine(ssortingpNS(xml)); }

Cela fera l’affaire 🙂

 foreach (XElement XE in Xml.DescendantsAndSelf()) { // Ssortingpping the namespace by setting the name of the element to it's localname only XE.Name = XE.Name.LocalName; // replacing all atsortingbutes with atsortingbutes that are not namespaces and their names are set to only the localname XE.ReplaceAtsortingbutes((from xatsortingb in XE.Atsortingbutes().Where(xa => !xa.IsNamespaceDeclaration) select new XAtsortingbute(xatsortingb.Name.LocalName, xatsortingb.Value))); } 

Reprenez-le, en C # – ligne ajoutée pour copier les atsortingbuts:

  static XElement ssortingpNS(XElement root) { XElement res = new XElement( root.Name.LocalName, root.HasElements ? root.Elements().Select(el => ssortingpNS(el)) : (object)root.Value ); res.ReplaceAtsortingbutes( root.Atsortingbutes().Where(attr => (!attr.IsNamespaceDeclaration))); return res; } 

La réponse obligatoire en utilisant XSLT:

                   

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 classe XmlTextWriter substituée qui supprime les espaces de noms. Je l’ai un peu modifié pour obtenir d’autres choses dans lesquelles je voulais, comme la mise en forme et la préservation de l’élément racine. Voici ce que j’ai dans mon projet pour le moment.

http://blogs.msdn.com/b/kaevans/archive/2004/08/02/206432.aspx

Classe

 ///  /// Modified XML writer that writes (almost) no namespaces out with pretty formatting ///  ///  public class XmlNoNamespaceWriter : XmlTextWriter { private bool _SkipAtsortingbute = false; private int _EncounteredNamespaceCount = 0; public XmlNoNamespaceWriter(TextWriter writer) : base(writer) { this.Formatting = System.Xml.Formatting.Indented; } public override void WriteStartElement(ssortingng prefix, ssortingng localName, ssortingng ns) { base.WriteStartElement(null, localName, null); } public override void WriteStartAtsortingbute(ssortingng prefix, ssortingng localName, ssortingng ns) { //If the prefix or localname are "xmlns", don't write it. //HOWEVER... if the 1st element (root?) has a namespace we will write it. if ((prefix.CompareTo("xmlns") == 0 || localName.CompareTo("xmlns") == 0) && _EncounteredNamespaceCount++ > 0) { _SkipAtsortingbute = true; } else { base.WriteStartAtsortingbute(null, localName, null); } } public override void WriteSsortingng(ssortingng text) { //If we are writing an atsortingbute, the text for the xmlns //or xmlns:prefix declaration would occur here. Skip //it if this is the case. if (!_SkipAtsortingbute) { base.WriteSsortingng(text); } } public override void WriteEndAtsortingbute() { //If we skipped the WriteStartAtsortingbute call, we have to //skip the WriteEndAtsortingbute call as well or else the XmlWriter //will have an invalid state. if (!_SkipAtsortingbute) { base.WriteEndAtsortingbute(); } //reset the boolean for the next atsortingbute. _SkipAtsortingbute = false; } public override void WriteQualifiedName(ssortingng localName, ssortingng ns) { //Always write the qualified name using only the //localname. base.WriteQualifiedName(localName, null); } } 

Usage

 //Save the updated document using our modified (almost) no-namespace XML writer using(StreamWriter sw = new StreamWriter(this.XmlDocumentPath)) using(XmlNoNamespaceWriter xw = new XmlNoNamespaceWriter(sw)) { //This variable is of type `XmlDocument` this.XmlDocumentRoot.Save(xw); } 

Et c’est la solution parfaite qui supprimera également les éléments XSI. (Si vous supprimez les xmlns et ne supprimez pas XSI, .Net crie à vous …)

 ssortingng xml = node.OuterXml; //Regex below finds ssortingngs that start with xmlns, may or may not have :and some text, then continue with = //and ", have a streach of text that does not contain quotes and end with ". similar, will happen to an atsortingbute // that starts with xsi. ssortingng strXMLPattern = @"xmlns(:\w+)?=""([^""]+)""|xsi(:\w+)?=""([^""]+)"""; xml = Regex.Replace(xml, strXMLPattern, ""); 

Ceci est une solution basée sur la réponse acceptée de Peter Stegnar.

Je l’ai utilisé, mais (comme l’ont fait remarquer andygjp et John Saunders), son code ignore les atsortingbuts .

Je devais aussi m’occuper des atsortingbuts, alors j’ai adapté son code. La version d’Andy était Visual Basic, c’est toujours c #.

Je sais que ça fait longtemps, mais peut-être que ça sauvera quelqu’un un jour.

  private static XElement RemoveAllNamespaces(XElement xmlDocument) { XElement xmlDocumentWithoutNs = removeAllNamespaces(xmlDocument); return xmlDocumentWithoutNs; } private static XElement removeAllNamespaces(XElement xmlDocument) { var ssortingpped = new XElement(xmlDocument.Name.LocalName); foreach (var atsortingbute in xmlDocument.Atsortingbutes().Where( atsortingbute => !atsortingbute.IsNamespaceDeclaration && Ssortingng.IsNullOrEmpty(atsortingbute.Name.NamespaceName))) { ssortingpped.Add(new XAtsortingbute(atsortingbute.Name.LocalName, atsortingbute.Value)); } if (!xmlDocument.HasElements) { ssortingpped.Value = xmlDocument.Value; return ssortingpped; } ssortingpped.Add(xmlDocument.Elements().Select( el => RemoveAllNamespaces(el))); return ssortingpped; } 

J’ai vraiment aimé l’endroit où Dexter s’y rend donc je l’ai traduit en une méthode d’extension «fluide»:

 ///  /// Returns the specified  /// without namespace qualifiers on elements and atsortingbutes. ///  /// The element public static XElement WithoutNamespaces(this XElement element) { if (element == null) return null; #region delegates: Func getChildNode = e => (e.NodeType == XmlNodeType.Element) ? (e as XElement).WithoutNamespaces() : e; Func> getAtsortingbutes = e => (e.HasAtsortingbutes) ? e.Atsortingbutes() .Where(a => !a.IsNamespaceDeclaration) .Select(a => new XAtsortingbute(a.Name.LocalName, a.Value)) : Enumerable.Empty(); #endregion return new XElement(element.Name.LocalName, element.Nodes().Select(getChildNode), getAtsortingbutes(element)); } 

L’approche «fluide» me permet de le faire:

 var xml = File.ReadAllText(presentationFile); var xDoc = XDocument.Parse(xml); var xRoot = xDoc.Root.WithoutNamespaces(); 

La réponse de Peter légèrement modifiée, cela fonctionnerait bien pour l’atsortingbut, y compris pour supprimer l’espace de noms et le préfixe. Un peu désolé pour le code est un peu moche.

  private static XElement RemoveAllNamespaces(XElement xmlDocument) { if (!xmlDocument.HasElements) { XElement xElement = new XElement(xmlDocument.Name.LocalName); xElement.Value = xmlDocument.Value; foreach (XAtsortingbute atsortingbute in xmlDocument.Atsortingbutes()) { xElement.Add(new XAtsortingbute(atsortingbute.Name.LocalName, atsortingbute.Value)); } return xElement; } else { XElement xElement = new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el))); foreach (XAtsortingbute atsortingbute in xmlDocument.Atsortingbutes()) { xElement.Add(new XAtsortingbute(atsortingbute.Name.LocalName, atsortingbute.Value)); } return xElement; } } 

Vous pouvez le faire en utilisant Linq:

 public static ssortingng RemoveAllNamespaces(ssortingng xmlDocument) { var xml = XElement.Parse(xmlDocument); xml.Descendants().Select(o => o.Name = o.Name.LocalName).ToArray(); return xml.ToSsortingng(); } 

Les réponses de Jimmy et Peter ont été d’une grande aide, mais ils ont supprimé tous les atsortingbuts, alors j’ai apporté une légère modification:

 Imports System.Runtime.ComstackrServices Friend Module XElementExtensions  _ Public Function RemoveAllNamespaces(ByVal element As XElement) As XElement If element.HasElements Then Dim cleanElement = RemoveAllNamespaces(New XElement(element.Name.LocalName, element.Atsortingbutes)) cleanElement.Add(element.Elements.Select(Function(el) RemoveAllNamespaces(el))) Return cleanElement Else Dim allAtsortingbutesExceptNamespaces = element.Atsortingbutes.Where(Function(attr) Not attr.IsNamespaceDeclaration) element.ReplaceAtsortingbutes(allAtsortingbutesExceptNamespaces) Return element End If End Function End Module 

Pour que les atsortingbuts fonctionnent, l’atsortingbut for loop doit être ajouté après la récursivité, il faut également vérifier si IsNamespaceDeclaration:

 private static XElement RemoveAllNamespaces(XElement xmlDocument) { XElement xElement; if (!xmlDocument.HasElements) { xElement = new XElement(xmlDocument.Name.LocalName) { Value = xmlDocument.Value }; } else { xElement = new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(RemoveAllNamespaces)); } foreach (var atsortingbute in xmlDocument.Atsortingbutes()) { if (!atsortingbute.IsNamespaceDeclaration) { xElement.Add(atsortingbute); } } return xElement; } 

Voici ma version VB.NET de Dexter Legaspi C # Version

 Shared Function RemoveAllNamespaces(ByVal e As XElement) As XElement Return New XElement(e.Name.LocalName, New Object() {(From n In e.Nodes Select If(TypeOf n Is XElement, RemoveAllNamespaces(TryCast(n, XElement)), n)), If(e.HasAtsortingbutes, (From a In e.Atsortingbutes Select a), Nothing)}) End Function 

Une autre solution qui prend en compte éventuellement les nœuds TEXT et ELEMENT, par exemple:

  text1  text2   

Code:

 using System.Linq; namespace System.Xml.Linq { public static class XElementTransformExtensions { public static XElement WithoutNamespaces(this XElement source) { return new XElement(source.Name.LocalName, source.Atsortingbutes().Select(WithoutNamespaces), source.Nodes().Select(WithoutNamespaces) ); } public static XAtsortingbute WithoutNamespaces(this XAtsortingbute source) { return !source.IsNamespaceDeclaration ? new XAtsortingbute(source.Name.LocalName, source.Value) : default(XAtsortingbute); } public static XNode WithoutNamespaces(this XNode source) { return source is XElement ? WithoutNamespaces((XElement)source) : source; } } } 

Sans recourir à une solution basée sur XSLT, si vous voulez une solution propre, élégante et intelligente, vous aurez besoin du support de la structure, en particulier, la structure des visiteurs peut devenir un jeu d’enfant. Malheureusement, ce n’est pas disponible ici.

Je l’ai implémenté inspiré par ExpressionVisitor de LINQ pour avoir une structure similaire. Avec cela, vous pouvez appliquer le motif visiteur aux objects XML (LINQ-to-). (J’ai fait des tests limités à ce sujet mais ça marche bien pour autant que je sache)

 public abstract class XObjectVisitor { public virtual XObject Visit(XObject node) { if (node != null) return node.Accept(this); return node; } public ReadOnlyCollection Visit(IEnumerable nodes) { return nodes.Select(node => Visit(node)) .Where(node => node != null) .ToList() .AsReadOnly(); } public T VisitAndConvert(T node) where T : XObject { if (node != null) return Visit(node) as T; return node; } public ReadOnlyCollection VisitAndConvert(IEnumerable nodes) where T : XObject { return nodes.Select(node => VisitAndConvert(node)) .Where(node => node != null) .ToList() .AsReadOnly(); } protected virtual XObject VisitAtsortingbute(XAtsortingbute node) { return node.Update(node.Name, node.Value); } protected virtual XObject VisitComment(XComment node) { return node.Update(node.Value); } protected virtual XObject VisitDocument(XDocument node) { return node.Update( node.Declaration, VisitAndConvert(node.Nodes()) ); } protected virtual XObject VisitElement(XElement node) { return node.Update( node.Name, VisitAndConvert(node.Atsortingbutes()), VisitAndConvert(node.Nodes()) ); } protected virtual XObject VisitDocumentType(XDocumentType node) { return node.Update( node.Name, node.PublicId, node.SystemId, node.InternalSubset ); } protected virtual XObject VisitProcessingInstruction(XProcessingInstruction node) { return node.Update( node.Target, node.Data ); } protected virtual XObject VisitText(XText node) { return node.Update(node.Value); } protected virtual XObject VisitCData(XCData node) { return node.Update(node.Value); } #region Implementation details internal InternalAccessor Accessor { get { return new InternalAccessor(this); } } internal class InternalAccessor { private XObjectVisitor visitor; internal InternalAccessor(XObjectVisitor visitor) { this.visitor = visitor; } internal XObject VisitAtsortingbute(XAtsortingbute node) { return visitor.VisitAtsortingbute(node); } internal XObject VisitComment(XComment node) { return visitor.VisitComment(node); } internal XObject VisitDocument(XDocument node) { return visitor.VisitDocument(node); } internal XObject VisitElement(XElement node) { return visitor.VisitElement(node); } internal XObject VisitDocumentType(XDocumentType node) { return visitor.VisitDocumentType(node); } internal XObject VisitProcessingInstruction(XProcessingInstruction node) { return visitor.VisitProcessingInstruction(node); } internal XObject VisitText(XText node) { return visitor.VisitText(node); } internal XObject VisitCData(XCData node) { return visitor.VisitCData(node); } } #endregion } public static class XObjectVisitorExtensions { #region XObject.Accept "instance" method public static XObject Accept(this XObject node, XObjectVisitor visitor) { Validation.CheckNullReference(node); Validation.CheckArgumentNull(visitor, "visitor"); // yay, easy dynamic dispatch Acceptor acceptor = new Acceptor(node as dynamic); return acceptor.Accept(visitor); } private class Acceptor { public Acceptor(XAtsortingbute node) : this(v => v.Accessor.VisitAtsortingbute(node)) { } public Acceptor(XComment node) : this(v => v.Accessor.VisitComment(node)) { } public Acceptor(XDocument node) : this(v => v.Accessor.VisitDocument(node)) { } public Acceptor(XElement node) : this(v => v.Accessor.VisitElement(node)) { } public Acceptor(XDocumentType node) : this(v => v.Accessor.VisitDocumentType(node)) { } public Acceptor(XProcessingInstruction node) : this(v => v.Accessor.VisitProcessingInstruction(node)) { } public Acceptor(XText node) : this(v => v.Accessor.VisitText(node)) { } public Acceptor(XCData node) : this(v => v.Accessor.VisitCData(node)) { } private Func accept; private Acceptor(Func accept) { this.accept = accept; } public XObject Accept(XObjectVisitor visitor) { return accept(visitor); } } #endregion #region XObject.Update "instance" method public static XObject Update(this XAtsortingbute node, XName name, ssortingng value) { Validation.CheckNullReference(node); Validation.CheckArgumentNull(name, "name"); Validation.CheckArgumentNull(value, "value"); return new XAtsortingbute(name, value); } public static XObject Update(this XComment node, ssortingng value = null) { Validation.CheckNullReference(node); return new XComment(value); } public static XObject Update(this XDocument node, XDeclaration declaration = null, params object[] content) { Validation.CheckNullReference(node); return new XDocument(declaration, content); } public static XObject Update(this XElement node, XName name, params object[] content) { Validation.CheckNullReference(node); Validation.CheckArgumentNull(name, "name"); return new XElement(name, content); } public static XObject Update(this XDocumentType node, ssortingng name, ssortingng publicId = null, ssortingng systemId = null, ssortingng internalSubset = null) { Validation.CheckNullReference(node); Validation.CheckArgumentNull(name, "name"); return new XDocumentType(name, publicId, systemId, internalSubset); } public static XObject Update(this XProcessingInstruction node, ssortingng target, ssortingng data) { Validation.CheckNullReference(node); Validation.CheckArgumentNull(target, "target"); Validation.CheckArgumentNull(data, "data"); return new XProcessingInstruction(target, data); } public static XObject Update(this XText node, ssortingng value = null) { Validation.CheckNullReference(node); return new XText(value); } public static XObject Update(this XCData node, ssortingng value = null) { Validation.CheckNullReference(node); return new XCData(value); } #endregion } public static class Validation { public static void CheckNullReference(T obj) where T : class { if (obj == null) throw new NullReferenceException(); } public static void CheckArgumentNull(T obj, ssortingng paramName) where T : class { if (obj == null) throw new ArgumentNullException(paramName); } } 

ps, cette implémentation particulière utilise des fonctionnalités .NET 4 pour rendre la mise en œuvre un peu plus facile / propre (utilisation des arguments dynamic et par défaut). Il ne devrait pas être trop difficile de le rendre compatible avec .NET 3.5, voire même compatible .NET 2.0.

Ensuite, pour implémenter le visiteur, voici une version généralisée qui peut changer plusieurs espaces de noms (et le préfixe utilisé).

 public class ChangeNamespaceVisitor : XObjectVisitor { private INamespaceMappingManager manager; public ChangeNamespaceVisitor(INamespaceMappingManager manager) { Validation.CheckArgumentNull(manager, "manager"); this.manager = manager; } protected INamespaceMappingManager Manager { get { return manager; } } private XName ChangeNamespace(XName name) { var mapping = Manager.GetMapping(name.Namespace); return mapping.ChangeNamespace(name); } private XObject ChangeNamespaceDeclaration(XAtsortingbute node) { var mapping = Manager.GetMapping(node.Value); return mapping.ChangeNamespaceDeclaration(node); } protected override XObject VisitAtsortingbute(XAtsortingbute node) { if (node.IsNamespaceDeclaration) return ChangeNamespaceDeclaration(node); return node.Update(ChangeNamespace(node.Name), node.Value); } protected override XObject VisitElement(XElement node) { return node.Update( ChangeNamespace(node.Name), VisitAndConvert(node.Atsortingbutes()), VisitAndConvert(node.Nodes()) ); } } // and all the gory implementation details public class NamespaceMappingManager : INamespaceMappingManager { private Dictionary namespaces = new Dictionary(); public NamespaceMappingManager Add(XNamespace fromNs, XNamespace toNs, ssortingng toPrefix = null) { var item = new NamespaceMapping(fromNs, toNs, toPrefix); namespaces.Add(item.FromNs, item); return this; } public INamespaceMapping GetMapping(XNamespace fromNs) { INamespaceMapping mapping; if (!namespaces.TryGetValue(fromNs, out mapping)) mapping = new NullMapping(); return mapping; } private class NullMapping : INamespaceMapping { public XName ChangeNamespace(XName name) { return name; } public XObject ChangeNamespaceDeclaration(XAtsortingbute node) { return node.Update(node.Name, node.Value); } } private class NamespaceMapping : INamespaceMapping { private XNamespace fromNs; private XNamespace toNs; private ssortingng toPrefix; public NamespaceMapping(XNamespace fromNs, XNamespace toNs, ssortingng toPrefix = null) { this.fromNs = fromNs ?? ""; this.toNs = toNs ?? ""; this.toPrefix = toPrefix; } public XNamespace FromNs { get { return fromNs; } } public XNamespace ToNs { get { return toNs; } } public ssortingng ToPrefix { get { return toPrefix; } } public XName ChangeNamespace(XName name) { return name.Namespace == fromNs ? toNs + name.LocalName : name; } public XObject ChangeNamespaceDeclaration(XAtsortingbute node) { if (node.Value == fromNs.NamespaceName) { if (toNs == XNamespace.None) return null; var xmlns = !Ssortingng.IsNullOrWhiteSpace(toPrefix) ? (XNamespace.Xmlns + toPrefix) : node.Name; return node.Update(xmlns, toNs.NamespaceName); } return node.Update(node.Name, node.Value); } } } public interface INamespaceMappingManager { INamespaceMapping GetMapping(XNamespace fromNs); } public interface INamespaceMapping { XName ChangeNamespace(XName name); XObject ChangeNamespaceDeclaration(XAtsortingbute node); } 

Et une petite méthode d’aide pour lancer la balle:

 T ChangeNamespace(T node, XNamespace fromNs, XNamespace toNs, ssortingng toPrefix = null) where T : XObject { return node.Accept( new ChangeNamespaceVisitor( new NamespaceMappingManager() .Add(fromNs, toNs, toPrefix) ) ) as T; } 

Ensuite, pour supprimer un espace de noms, vous pouvez l’appeler ainsi:

 var doc = ChangeNamespace(XDocument.Load(pathToXml), fromNs: "http://schema.peters.com/doc_353/1/Types", toNs: null); 

En utilisant ce visiteur, vous pouvez écrire un INamespaceMappingManager pour supprimer tous les espaces de noms.

 T RemoveAllNamespaces(T node) where T : XObject { return node.Accept( new ChangeNamespaceVisitor(new RemoveNamespaceMappingManager()) ) as T; } public class RemoveNamespaceMappingManager : INamespaceMappingManager { public INamespaceMapping GetMapping(XNamespace fromNs) { return new RemoveNamespaceMapping(); } private class RemoveNamespaceMapping : INamespaceMapping { public XName ChangeNamespace(XName name) { return name.LocalName; } public XObject ChangeNamespaceDeclaration(XAtsortingbute node) { return null; } } } 

Une solution simple qui renomme les éléments sur place, sans créer de copie, et remplit très bien le rôle de remplacer les atsortingbuts.

 public void RemoveAllNamespaces(ref XElement value) { List atsortingbutesToRemove = new List(); foreach (void e_loopVariable in value.DescendantsAndSelf) { e = e_loopVariable; if (e.Name.Namespace != XNamespace.None) { e.Name = e.Name.LocalName; } foreach (void a_loopVariable in e.Atsortingbutes) { a = a_loopVariable; if (a.IsNamespaceDeclaration) { //do not keep it at all atsortingbutesToRemove.Add(a); } else if (a.Name.Namespace != XNamespace.None) { e.SetAtsortingbuteValue(a.Name.LocalName, a.Value); atsortingbutesToRemove.Add(a); } } } foreach (void a_loopVariable in atsortingbutesToRemove) { a = a_loopVariable; a.Remove(); } } 

Note: cela ne préserve pas toujours l’ordre d’atsortingbut d’origine, mais je suis sûr que vous pourriez le changer assez facilement si cela est important pour vous.

Notez également que cela pourrait également générer une exception si vous aviez des atsortingbuts 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 produirait une chaîne valide qui serait 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 définitivement pas les espaces de noms comme je le voulais.

Ajouter mon qui nettoie également le nom des nœuds qui ont des préfixes d’espace de noms:

  public static ssortingng RemoveAllNamespaces(XElement element) { ssortingng tex = element.ToSsortingng(); var nsitems = element.DescendantsAndSelf().Select(n => n.ToSsortingng().Split(' ', '>')[0].Split('< ')[1]).Where(n => n.Contains(":")).DistinctBy(n => n).ToArray(); //Namespace prefix on nodes:  tex = nsitems.Aggregate(tex, (current, nsnode) => current.Replace("< "+nsnode + "", "<" + nsnode.Split(':')[1] + "")); tex = nsitems.Aggregate(tex, (current, nsnode) => current.Replace(" d.Atsortingbutes().Where(a => a.IsNamespaceDeclaration || a.ToSsortingng().Contains(":"))).DistinctBy(o => o.Value); tex = items.Aggregate(tex, (current, xAtsortingbute) => current.Replace(xAtsortingbute.ToSsortingng(), "")); return tex; } 

I sortinged the first few solutions and didn’t work for me. Mainly the problem with atsortingbutes being removed like the other have already mentioned. I would say my approach is very similar to Jimmy by using the XElement constructors that taking object as parameters.

 public static XElement RemoveAllNamespaces(this XElement element) { return new XElement(element.Name.LocalName, element.HasAtsortingbutes ? element.Atsortingbutes().Select(a => new XAtsortingbute(a.Name.LocalName, a.Value)) : null, element.HasElements ? element.Elements().Select(e => RemoveAllNamespaces(e)) : null, element.Value); } 

my answer, ssortingng-manipulation-based,
lite-most code,

 public static ssortingng hilangkanNamespace(ssortingng instrXML) { char chrOpeningTag = '< '; char chrClosingTag = '>'; char chrSpasi = ' '; int intStartIndex = 0; do { int intIndexKu = instrXML.IndexOf(chrOpeningTag, intStartIndex); if (intIndexKu < 0) break; //kalau dah ga ketemu keluar int intStart = instrXML.IndexOfAny(new char[] { chrSpasi, chrClosingTag }, intIndexKu + 1); //mana yang ketemu duluan if (intStart < 0) break; //kalau dah ga ketemu keluar int intStop = instrXML.IndexOf(chrClosingTag, intStart); if (intStop < 0) break; //kalau dah ga ketemu keluar else intStop--; //exclude si closingTag int intLengthToStrip = intStop - intStart + 1; instrXML = instrXML.Remove(intStart, intLengthToStrip); intStartIndex = intStart; } while (true); return instrXML; } 

user892217’s answer is almost correct. It won’t comstack as is, so needs a slight correction to the recursive call:

 private static XElement RemoveAllNamespaces(XElement xmlDocument) { XElement xElement; if (!xmlDocument.HasElements) { xElement = new XElement(xmlDocument.Name.LocalName) { Value = xmlDocument.Value }; } else { xElement = new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(x => RemoveAllNamespaces(x))); } foreach (var atsortingbute in xmlDocument.Atsortingbutes()) { if (!atsortingbute.IsNamespaceDeclaration) { xElement.Add(atsortingbute); } } return xElement; } 

Cela a fonctionné pour moi.

  FileStream fs = new FileStream(filePath, FileMode.Open); StreamReader sr = new StreamReader(fs); DataSet ds = new DataSet(); ds.ReadXml(sr); ds.Namespace = ""; ssortingng outXML = ds.GetXml(); ds.Dispose(); sr.Dispose(); fs.Dispose(); 

After much searching for a solution to this very issue, this particular page seemed to have the most beef…however, nothing quite fit exactly, so I took the old-fashioned way and just parsed the stuff out I wanted out. J’espère que cela aide quelqu’un. (Note: this also removes the SOAP or similar envelope stuff.)

  public static ssortingng RemoveNamespaces(ssortingng psXml) { // // parse through the passed XML, and remove any and all namespace references...also // removes soap envelope/header(s)/body, or any other references via ":" entities, // leaving all data intact // ssortingng xsXml = "", xsCurrQtChr = ""; int xiPos = 0, xiLastPos = psXml.Length - 1; bool xbInNode = false; while (xiPos < = xiLastPos) { string xsCurrChr = psXml.Substring(xiPos, 1); xiPos++; if (xbInNode) { if (xsCurrChr == ":") { // soap envelope or body (or some such) // we'll strip these node wrappers completely // need to first strip the beginning of it off (ie "") xsChr = "x"; // stay in loop...this is not end of node } } } } while (xsChr != ">" && xiPos < = xiLastPos); xiPos++; // skip over closing ">" xbInNode = false; } else { if (xsCurrChr == ">") { xbInNode = false; xsXml += xsCurrChr; } else { if (xsCurrChr == " " || xsCurrChr == "\t") { // potential namespace...let's check...next character must be "/" // or more white space, and if not, skip until we find such ssortingng xsChr = ""; int xiOrgLen = xsXml.Length; xsXml += xsCurrChr; do { if (xiPos < = xiLastPos) { xsChr = psXml.Substring(xiPos, 1); xiPos++; if (xsChr == " " || xsChr == "\r" || xsChr == "\n" || xsChr == "\t") { // carry on..white space xsXml += xsChr; } else { if (xsChr == "/" || xsChr == ">") { xsXml += xsChr; } else { // namespace! - get rid of it xsXml = xsXml.Subssortingng(0, xiOrgLen - 0); // first, truncate any added whitespace // next, peek forward until we find "/" or ">" ssortingng xsQt = ""; do { if (xiPos < = xiLastPos) { xsChr = psXml.Substring(xiPos, 1); xiPos++; if (xsQt.Length > 0) { if (xsChr == xsQt) xsQt = ""; else xsChr = "x"; } else { if (xsChr == "'" || xsChr == "\"") xsQt = xsChr; } } } while (xsChr != ">" && xsChr != "/" && xiPos < = xiLastPos); if (xsChr == ">" || xsChr == "/") xsXml += xsChr; xbInNode = false; } } } } while (xsChr != ">" && xsChr != "/" && xiPos < = xiLastPos); } else { xsXml += xsCurrChr; } } } } else { // // if not currently inside a node, then we are in a value (or about to enter a new node) // xsXml += xsCurrChr; if (xsCurrQtChr.Length == 0) { if (xsCurrChr == "<") { xbInNode = true; } } else { // // currently inside a quoted string // if (xsCurrQtChr == xsCurrChr) { // finishing quoted string xsCurrQtChr = ""; } } } } return (xsXml); } 

Here’s are Regex Replace one liner:

 public static ssortingng RemoveNamespaces(this ssortingng xml) { return Regex.Replace(xml, "((?< =<|<\\/)|(?<= ))[A-Za-z0-9]+:| xmlns(:[A-Za-z0-9]+)?=\".*?\"", ""); } 

Here's a sample: https://regex101.com/r/fopydN/6

Warning:there might be edge cases!

Without recreating whole node hierarchy:

 private static void RemoveDefNamespace(XElement element) { var defNamespase = element.Atsortingbute("xmlns"); if (defNamespase != null) defNamespase.Remove(); element.Name = element.Name.LocalName; foreach (var child in element.Elements()) { RemoveDefNamespace(child); } } 

Bit late to the party on this one but here’s what I used recently:

 var doc = XDocument.Parse(xmlSsortingng); doc.Root.DescendantNodesAndSelf().OfType().Atsortingbutes().Where(att => att.IsNamespaceDeclaration).Remove(); 

(taken from this MSDN Thread )

Edit As per the comment below, it appears that while this removes the namespace prefix from the nodes it doesn’t actually remove the xmlns atsortingbute. To do that you need to also reset the name of each node to it’s localname (eg name minus namespace)

 foreach (var node in doc.Root.DescendantNodesAndSelf().OfType()) { node.Name = node.Name.LocalName; } 

Here is a regex based solution to this problem…

  private XmlDocument RemoveNS(XmlDocument doc) { var xml = doc.OuterXml; var newxml = Regex.Replace(xml, @"xmlns[:xsi|:xsd]*="".*?""",""); var newdoc = new XmlDocument(); newdoc.LoadXml(newxml); return newdoc; } 

I think this is shortest answer(but for constuctions like , you will have another discussion, I also have regex to convert "" to ” ” but it wasn’t optimized, If someone ask me I will share it. So, my solution is:

  public ssortingng RemoveAllNamespaces(ssortingng xmlDocument) { return Regex.Replace(xmlDocument, @"\sxmlns(\u003A\w+)?\u003D\u0022.+\u0022", " "); }