How to remove all namespaces from XML with C#?
Asked Answered
N

31

118

I am looking for the clean, elegant and smart solution to remove namespacees from all XML elements? How would function to do that look like?

Defined interface:

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

Sample XML to remove NS from:

<?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>

After we call RemoveAllNamespaces(xmlWithLotOfNs), we should get:

  <?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>

Preffered language of solution is C# on .NET 3.5 SP1.

Nahshon answered 12/6, 2009 at 15:3 Comment(2)
@JohnSaunders: You are right. But it this particular case I have to do some system integration. And this was the only option back then.Nahshon
@PeterStegnar the error is usually the hacker who created the legacy formats. Often, developers misuse xml chronically. Namespaces the first crazy important feature to be tossed aside.Nat
N
123

Well, here is the final answer. I have used great Jimmy idea (which unfortunately is not complete itself) and complete recursion function to work properly.

Based on interface:

string RemoveAllNamespaces(string xmlDocument);

I represent here final clean and universal C# solution for removing XML namespaces:

//Implemented based on interface, not part of algorithm
public static string RemoveAllNamespaces(string xmlDocument)
{
    XElement xmlDocumentWithoutNs = RemoveAllNamespaces(XElement.Parse(xmlDocument));

    return xmlDocumentWithoutNs.ToString();
}

//Core recursion function
 private static XElement RemoveAllNamespaces(XElement xmlDocument)
    {
        if (!xmlDocument.HasElements)
        {
            XElement xElement = new XElement(xmlDocument.Name.LocalName);
            xElement.Value = xmlDocument.Value;

            foreach (XAttribute attribute in xmlDocument.Attributes())
                xElement.Add(attribute);

            return xElement;
        }
        return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el)));
    }

It's working 100%, but I have not tested it much so it may not cover some special cases... But it is good base to start.

Nahshon answered 12/6, 2009 at 18:43 Comment(12)
How well does that work with attributes that have namespaces? In fact, your code just ignores attributes entirely.Dyeing
I realize namespaces may be useful in some applications, but not at all in mine; they were causing a huge annoyance. This solution worked for me.Pirali
@John Saunders - Yeah I used that solution and I realized you were right. I'm posting an updated solution as an answerChapiter
This solution did NOT work for me, as the code removes all attributes as well as the namespaces. Of course, a few changes might work to see if the attribute being removed is a namespace or attributePurgatory
@KonradMorawski, unfortunately, I don't see your answer here. :(Passepartout
@RamiA. indeed. I had deleted it for some reason, which I can't remember for the life of me. It's undeleted now.Chapiter
+1: This is great! I get to traverse the document tree at no extra cost, and so I added some code to remove unwanted EntityKey values, as well!Greeneyed
This did not work for me to remove namespaces from a WCF DataContract.Ruminant
Careful as it removes more than namespaces (as in all attributes on root node if xmlfragment)Phosphorite
I tried removing the namespace using XmlSerializerNamespaces, setting the UTF encoding to false new UTF8Encoding(false).GetBytes(xml); and none of that worked.. This was only thing that worked as expected, thanks.Epigoni
negative.. It ended up removing attributes.. There is another answer which is more appropriatePannier
this will remove all the attribute in elements which have child elements, solution will be use"return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el)), xmlDocument.Attributes())";Godber
M
67

The tagged most useful answer has two flaws:

  • It ignores attributes
  • It doesn't work with "mixed mode" elements

Here is my take on this:

 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.HasAttributes) ? 
            (from a in e.Attributes() 
               where (!a.IsNamespaceDeclaration)  
               select new XAttribute(a.Name.LocalName, a.Value)) : null);
  }          

Sample code here.

Masterson answered 30/8, 2011 at 2:13 Comment(7)
Unfortunately, this did not work for me, the same xml entered was returned. :(Passepartout
@RamiA. can you post a snippet of the code so we can see what the problem is?Masterson
Didn't work for me either. I guess since you're copying the attributes you're simply copying over the xmlns as well.Fibriform
This works. I have used it...however i realized it's not thorough cleaning in the sense that it doesn't remove the actual xmlns attributes that defines the namespace...so I updated it to do just that...and added a gist example.Masterson
Need to add (from a in e.Attributes().DistinctBy(x => x.Name.LocalName) for case lang=""ru-ru"" xml:lang=""ru-ru""Mungovan
How about loading the whole xml file to a string buffer and removig all xmlns="...." atributes with a little help from regular expression? ;))Gravitate
@Gravitate that might work for smaller XML, but for very large XML, it will give you an out-of-memory exception (I know from experience).Dichlorodifluoromethane
R
39

That will do the trick :-)

foreach (XElement XE in Xml.DescendantsAndSelf())
{
    // Stripping the namespace by setting the name of the element to it's localname only
    XE.Name = XE.Name.LocalName;
    // replacing all attributes with attributes that are not namespaces and their names are set to only the localname
    XE.ReplaceAttributes((from xattrib in XE.Attributes().Where(xa => !xa.IsNamespaceDeclaration) select new XAttribute(xattrib.Name.LocalName, xattrib.Value)));
}
Retardation answered 14/2, 2013 at 0:24 Comment(2)
Yo this works great, not only does it work, it doesn't even affect the file it's writing the data too the Xelement using the DescendantAndself method. thanks man!Pettigrew
works for me. Also handles CDATA which other solutions loose along the way.Endways
Y
28

the obligatory answer using LINQ:

static XElement stripNS(XElement root) {
    return new XElement(
        root.Name.LocalName,
        root.HasElements ? 
            root.Elements().Select(el => stripNS(el)) :
            (object)root.Value
    );
}
static void Main() {
    var xml = XElement.Parse(@"<?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>");
    Console.WriteLine(stripNS(xml));
}
Y answered 12/6, 2009 at 15:37 Comment(7)
I guess you can show the VB folks you can have an XML literal in C# after all.Ambidextrous
@Robert, that's not an XML literal. It's a string. There's a big difference!Money
Jimmy, you are close but not there yet. :) I am writing final solution based on your idea. I will post it there.Nahshon
you're right :) while you're at it, I offer my own version of the fix.Y
This strips out all attributes, not just namespaces. See florian's answer for fix.Bradwell
@Money xml is a subset of string, so there is no difference at all ;)Nat
@Nat I was replying to Robert's joke. If you've ever seen XML literals in VB.NET, you'd know they're quite different from strings. Of course, in C#, there is no difference because strings are all you have.Money
P
16

Pick it up again, in C# - added line for copying the attributes:

    static XElement stripNS(XElement root)
    {
        XElement res = new XElement(
            root.Name.LocalName,
            root.HasElements ?
                root.Elements().Select(el => stripNS(el)) :
                (object)root.Value
        );

        res.ReplaceAttributes(
            root.Attributes().Where(attr => (!attr.IsNamespaceDeclaration)));

        return res;
    }
Petra answered 9/2, 2011 at 23:13 Comment(2)
Works for the root element, but not for nested elements; the namespaces seems to just get renamed, maybe automatically by XElement.ToString().Passepartout
Exactly what I needed to remove all namespaces, but keep attributes.Gaelic
L
11

The obligatory answer using XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="no" encoding="UTF-8"/>

  <xsl:template match="/|comment()|processing-instruction()">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>
Linnealinnean answered 12/6, 2009 at 15:43 Comment(6)
+1 for the "obligatory". :-) I still wonder why removing namespaces would be a smart decision. This probably crashes and burns on <element ns:attr="a" attr="b"/>.Kamseen
Oh sure, but every NS removing technique will to a greater or lesser extent. As or validity, I can tell you where I have needed it: importing third party XML where they can't sort out a valid XSD but insist on namespacing. Practicality rules ultimately.Linnealinnean
@annakata: Namespaces are perfectly usable without XSD, and very useful where nodes come from multiple sources. You just have to remember that nodes are named by namespace+localname always (and the namespace tag (or prefix) is just a local document detail).Hildegard
@annakata: The solution is simpler than you think. Stop enabling. Refuse to use any technique which does not understand XML. The only reason we're still forced to use such garbage is because people keep saying, "yes", when they need to say "no" a bit more often. The standards are over 10 years old! Why else do we still have software that doesn't understand XML Namespaces, except that we continue to enable it to exist?Dyeing
@John - ha, there are those things which should be done, and there are those things which the management deems will be done. All is for the best in the best of all possible worlds.Linnealinnean
@Kamseen one use case could be if you need to convert to JSON and namespace declarations interfere with that process.Lessor
L
11

I know this question is supposedly solved, but I wasn't totally happy with the way it was implemented. I found another source over here on the MSDN blogs that has an overridden XmlTextWriter class that strips out the namespaces. I tweaked it a bit to get some other things I wanted in such as pretty formatting and preserving the root element. Here is what I have in my project at the moment.

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

Class

/// <summary>
/// Modified XML writer that writes (almost) no namespaces out with pretty formatting
/// </summary>
/// <seealso cref="http://blogs.msdn.com/b/kaevans/archive/2004/08/02/206432.aspx"/>
public class XmlNoNamespaceWriter : XmlTextWriter
{
    private bool _SkipAttribute = false;
    private int _EncounteredNamespaceCount = 0;

    public XmlNoNamespaceWriter(TextWriter writer)
        : base(writer)
    {
        this.Formatting = System.Xml.Formatting.Indented;
    }

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        base.WriteStartElement(null, localName, null);
    }

    public override void WriteStartAttribute(string prefix, string localName, string 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)
        {
            _SkipAttribute = true;
        }
        else
        {
            base.WriteStartAttribute(null, localName, null);
        }
    }

    public override void WriteString(string text)
    {
        //If we are writing an attribute, the text for the xmlns
        //or xmlns:prefix declaration would occur here.  Skip
        //it if this is the case.
        if (!_SkipAttribute)
        {
            base.WriteString(text);
        }
    }

    public override void WriteEndAttribute()
    {
        //If we skipped the WriteStartAttribute call, we have to
        //skip the WriteEndAttribute call as well or else the XmlWriter
        //will have an invalid state.
        if (!_SkipAttribute)
        {
            base.WriteEndAttribute();
        }
        //reset the boolean for the next attribute.
        _SkipAttribute = false;
    }

    public override void WriteQualifiedName(string localName, string 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);
}
Lailaibach answered 12/7, 2011 at 5:7 Comment(1)
Your answer is the only one that doesn't feel like a hack, however, the original sample in the referenced blog post is more correct because if you don't remove the namespace in the root node, then all child nodes and attributes without a namespace will inherit the root namespace.Mountfort
W
11

And this is the perfect solution that will also remove XSI elements. (If you remove the xmlns and don't remove XSI, .Net shouts at you...)

string xml = node.OuterXml;
//Regex below finds strings 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 attribute
// that starts with xsi.
string strXMLPattern = @"xmlns(:\w+)?=""([^""]+)""|xsi(:\w+)?=""([^""]+)""";
xml = Regex.Replace(xml, strXMLPattern, "");
Wrench answered 15/5, 2012 at 17:9 Comment(2)
I should read this 2 hours ago. Did almost same regex, the only thing that worked, in complex XML, with many namespaces, attributes, etc.Cosignatory
Keep in mind you still might have to clean up elements like for example <xxx:tagname>. I used following code (disclaimer, works on my machine): Regex.Replace(xmlStr, @"<(/?)([^>\s:]+):([^>]+)>", "<$1$3>")Hobard
C
8

This is a solution based on Peter Stegnar's accepted answer.

I used it, but (as andygjp and John Saunders remarked) his code ignores attributes.

I needed to take care of attributes too, so I adapted his code. Andy's version was Visual Basic, this is still c#.

I know it's been a while, but perhaps it'll save somebody some time one day.

    private static XElement RemoveAllNamespaces(XElement xmlDocument)
    {
        XElement xmlDocumentWithoutNs = removeAllNamespaces(xmlDocument);
        return xmlDocumentWithoutNs;
    }

    private static XElement removeAllNamespaces(XElement xmlDocument)
    {
        var stripped = new XElement(xmlDocument.Name.LocalName);            
        foreach (var attribute in
                xmlDocument.Attributes().Where(
                attribute =>
                    !attribute.IsNamespaceDeclaration &&
                    String.IsNullOrEmpty(attribute.Name.NamespaceName)))
        {
            stripped.Add(new XAttribute(attribute.Name.LocalName, attribute.Value));
        }
        if (!xmlDocument.HasElements)
        {
            stripped.Value = xmlDocument.Value;
            return stripped;
        }
        stripped.Add(xmlDocument.Elements().Select(
            el =>
                RemoveAllNamespaces(el)));            
        return stripped;
    }
Chapiter answered 28/9, 2011 at 14:50 Comment(0)
W
6

I really liked where Dexter is going up there so I translated it into a “fluent” extension method:

/// <summary>
/// Returns the specified <see cref="XElement"/>
/// without namespace qualifiers on elements and attributes.
/// </summary>
/// <param name="element">The element</param>
public static XElement WithoutNamespaces(this XElement element)
{
    if (element == null) return null;

    #region delegates:

        Func<XNode, XNode> getChildNode = e => (e.NodeType == XmlNodeType.Element) ? (e as XElement).WithoutNamespaces() : e;

        Func<XElement, IEnumerable<XAttribute>> getAttributes = e => (e.HasAttributes) ?
            e.Attributes()
                .Where(a => !a.IsNamespaceDeclaration)
                .Select(a => new XAttribute(a.Name.LocalName, a.Value))
            :
            Enumerable.Empty<XAttribute>();

        #endregion

    return new XElement(element.Name.LocalName,
        element.Nodes().Select(getChildNode),
        getAttributes(element));
}

The “fluent” approach allows me to do this:

var xml = File.ReadAllText(presentationFile);
var xDoc = XDocument.Parse(xml);
var xRoot = xDoc.Root.WithoutNamespaces();
Withdrawal answered 21/12, 2015 at 19:59 Comment(2)
Thanks for this solution! Works great for my issue.Roer
So this was ideal BECAUSE it worked on the attributes. Was able to use this without a problem. ThanksCharacteristically
R
4

You can do that using Linq:

public static string RemoveAllNamespaces(string xmlDocument)
{
    var xml = XElement.Parse(xmlDocument);
    xml.Descendants().Select(o => o.Name = o.Name.LocalName).ToArray();
    return xml.ToString();
}
Ruffner answered 14/12, 2012 at 15:12 Comment(0)
R
4

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

var doc = XDocument.Parse(xmlString);
doc.Root.DescendantNodesAndSelf().OfType<XElement>().Attributes().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 attribute. 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<XElement>())
{
    node.Name = node.Name.LocalName;
}
Ring answered 3/11, 2017 at 12:35 Comment(2)
Doesn't seem to work? It finds all the namespace declarations, but calling Remove() on that collection doesn't do anything. I tried result.ToString(), and the resulting string still have the xmlns attribute. Am I doing something wrong?Y
It worked for what I needed at the time but now I look back on it it's not 100%. It does remove the namespace prefixes from the nodes (which is what I needed) but you're right about it leaving the xmlns attribute behind. Weirdly, that attribute is not recognised by any of the XDocument methods either!Ring
T
3

Slightly modified Peter's answer, this would works fine for the attribute as well, including remove the namespace and prefix. A bit sorry for the code looks a bit ugly.

 private static XElement RemoveAllNamespaces(XElement xmlDocument)
        {
            if (!xmlDocument.HasElements)
            {
                XElement xElement = new XElement(xmlDocument.Name.LocalName);
                xElement.Value = xmlDocument.Value;

                foreach (XAttribute attribute in xmlDocument.Attributes())
                {
                    xElement.Add(new XAttribute(attribute.Name.LocalName, attribute.Value));
                }

                return xElement;
            }

            else
            {
                XElement xElement = new XElement(xmlDocument.Name.LocalName,  xmlDocument.Elements().Select(el => RemoveAllNamespaces(el)));

                foreach (XAttribute attribute in xmlDocument.Attributes())
                {
                    xElement.Add(new XAttribute(attribute.Name.LocalName, attribute.Value));
                }

                return xElement;
            }

    }
Truitt answered 13/8, 2012 at 4:55 Comment(1)
+1 This worked for me. However, it leaves attributes that were part of the namespace definition (just the xmlns prefix removed) but they don't currently affect serialization.Passepartout
F
2

Here's are Regex Replace one liner:

public static string RemoveNamespaces(this string 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!

Fraternal answered 28/12, 2016 at 22:20 Comment(0)
S
1

The reply's by Jimmy and Peter were a great help, but they actually removed all attributes, so I made a slight modification:

Imports System.Runtime.CompilerServices

Friend Module XElementExtensions

    <Extension()> _
    Public Function RemoveAllNamespaces(ByVal element As XElement) As XElement
        If element.HasElements Then
            Dim cleanElement = RemoveAllNamespaces(New XElement(element.Name.LocalName, element.Attributes))
            cleanElement.Add(element.Elements.Select(Function(el) RemoveAllNamespaces(el)))
            Return cleanElement
        Else
            Dim allAttributesExceptNamespaces = element.Attributes.Where(Function(attr) Not attr.IsNamespaceDeclaration)
            element.ReplaceAttributes(allAttributesExceptNamespaces)
            Return element
        End If

    End Function

End Module
Seamark answered 8/10, 2010 at 6:47 Comment(0)
I
1

For attributes to work the for loop for adding attribute should go after recursion, also need to check if 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 attribute in xmlDocument.Attributes())
    {
        if (!attribute.IsNamespaceDeclaration)
        {
            xElement.Add(attribute);
        }
    }

    return xElement;
}
Interlocutor answered 28/8, 2012 at 22:29 Comment(0)
T
1

Here is my VB.NET version of 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.HasAttributes, (From a In e.Attributes Select a), Nothing)})
End Function
Transonic answered 2/9, 2013 at 16:57 Comment(0)
J
1

Another solution that takes into account possibly interleaving TEXT and ELEMENT nodes, e.g.:

<parent>
    text1
    <child1/>
    text2
    <child2/>
</parent>

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.Attributes().Select(WithoutNamespaces),
                source.Nodes().Select(WithoutNamespaces)
            );
        }

        public static XAttribute WithoutNamespaces(this XAttribute source)
        {
            return !source.IsNamespaceDeclaration
                ? new XAttribute(source.Name.LocalName, source.Value)
                : default(XAttribute);
        }

        public static XNode WithoutNamespaces(this XNode source)
        {
            return
                source is XElement
                    ? WithoutNamespaces((XElement)source)
                    : source;
        }
    }
}
Jeanajeanbaptiste answered 10/9, 2013 at 11:56 Comment(0)
B
1

Without resorting to an XSLT-based solution, if you want clean, elegant and smart, you'd need some support from the framework, in particular, the visitor pattern could make this a breeze. Unfortunately, it's not available here.

I've implemented it inspired by LINQ's ExpressionVisitor to have a similar structure to it. With this, you can apply the visitor pattern to (LINQ-to-) XML objects. (I've done limited testing on this but it works well as far as I can tell)

public abstract class XObjectVisitor
{
    public virtual XObject Visit(XObject node)
    {
        if (node != null)
            return node.Accept(this);
        return node;
    }

    public ReadOnlyCollection<XObject> Visit(IEnumerable<XObject> nodes)
    {
        return nodes.Select(node => Visit(node))
            .Where(node => node != null)
            .ToList()
            .AsReadOnly();
    }

    public T VisitAndConvert<T>(T node) where T : XObject
    {
        if (node != null)
            return Visit(node) as T;
        return node;
    }

    public ReadOnlyCollection<T> VisitAndConvert<T>(IEnumerable<T> nodes) where T : XObject
    {
        return nodes.Select(node => VisitAndConvert(node))
            .Where(node => node != null)
            .ToList()
            .AsReadOnly();
    }

    protected virtual XObject VisitAttribute(XAttribute 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.Attributes()),
            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 VisitAttribute(XAttribute node) { return visitor.VisitAttribute(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(XAttribute node) : this(v => v.Accessor.VisitAttribute(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<XObjectVisitor, XObject> accept;
        private Acceptor(Func<XObjectVisitor, XObject> accept) { this.accept = accept; }

        public XObject Accept(XObjectVisitor visitor) { return accept(visitor); }
    }
    #endregion

    #region XObject.Update "instance" method
    public static XObject Update(this XAttribute node, XName name, string value)
    {
        Validation.CheckNullReference(node);
        Validation.CheckArgumentNull(name, "name");
        Validation.CheckArgumentNull(value, "value");

        return new XAttribute(name, value);
    }
    public static XObject Update(this XComment node, string 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, string name, string publicId = null, string systemId = null, string internalSubset = null)
    {
        Validation.CheckNullReference(node);
        Validation.CheckArgumentNull(name, "name");

        return new XDocumentType(name, publicId, systemId, internalSubset);
    }
    public static XObject Update(this XProcessingInstruction node, string target, string data)
    {
        Validation.CheckNullReference(node);
        Validation.CheckArgumentNull(target, "target");
        Validation.CheckArgumentNull(data, "data");

        return new XProcessingInstruction(target, data);
    }
    public static XObject Update(this XText node, string value = null)
    {
        Validation.CheckNullReference(node);

        return new XText(value);
    }
    public static XObject Update(this XCData node, string value = null)
    {
        Validation.CheckNullReference(node);

        return new XCData(value);
    }
    #endregion
}

public static class Validation
{
    public static void CheckNullReference<T>(T obj) where T : class
    {
        if (obj == null)
            throw new NullReferenceException();
    }

    public static void CheckArgumentNull<T>(T obj, string paramName) where T : class
    {
        if (obj == null)
            throw new ArgumentNullException(paramName);
    }
}

p.s., this particular implementation uses some .NET 4 features to make implementation a bit easier/cleaner (usage of dynamic and default arguments). It shouldn't be too dificult to make it .NET 3.5 compatible, perhaps even .NET 2.0 compatible.

Then to implement the visitor, here's a generalized one that can change multiple namespaces (and the prefix used).

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(XAttribute node)
    {
        var mapping = Manager.GetMapping(node.Value);
        return mapping.ChangeNamespaceDeclaration(node);
    }

    protected override XObject VisitAttribute(XAttribute 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.Attributes()),
            VisitAndConvert(node.Nodes())
        );
    }
}

// and all the gory implementation details
public class NamespaceMappingManager : INamespaceMappingManager
{
    private Dictionary<XNamespace, INamespaceMapping> namespaces = new Dictionary<XNamespace, INamespaceMapping>();

    public NamespaceMappingManager Add(XNamespace fromNs, XNamespace toNs, string 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(XAttribute node)
        {
            return node.Update(node.Name, node.Value);
        }
    }

    private class NamespaceMapping : INamespaceMapping
    {
        private XNamespace fromNs;
        private XNamespace toNs;
        private string toPrefix;
        public NamespaceMapping(XNamespace fromNs, XNamespace toNs, string toPrefix = null)
        {
            this.fromNs = fromNs ?? "";
            this.toNs = toNs ?? "";
            this.toPrefix = toPrefix;
        }

        public XNamespace FromNs { get { return fromNs; } }
        public XNamespace ToNs { get { return toNs; } }
        public string ToPrefix { get { return toPrefix; } }

        public XName ChangeNamespace(XName name)
        {
            return name.Namespace == fromNs
                ? toNs + name.LocalName
                : name;
        }

        public XObject ChangeNamespaceDeclaration(XAttribute node)
        {
            if (node.Value == fromNs.NamespaceName)
            {
                if (toNs == XNamespace.None)
                    return null;
                var xmlns = !String.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(XAttribute node);
}

And a little helper method to get the ball rolling:

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

Then to remove a namespace, you could call it like so:

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

Using this visitor, you can write a INamespaceMappingManager to remove all namespaces.

T RemoveAllNamespaces<T>(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(XAttribute node)
        {
            return null;
        }
    }
}
Bridewell answered 1/1, 2014 at 13:16 Comment(0)
E
1

Simple solution that actually renames the elements in-place, not creating a copy, and does a pretty good job of replacing the attributes.

public void RemoveAllNamespaces(ref XElement value)
{
  List<XAttribute> attributesToRemove = new List<XAttribute>();
  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.Attributes) {
      a = a_loopVariable;
      if (a.IsNamespaceDeclaration) {
        //do not keep it at all
        attributesToRemove.Add(a);
      } else if (a.Name.Namespace != XNamespace.None) {
        e.SetAttributeValue(a.Name.LocalName, a.Value);
        attributesToRemove.Add(a);
      }
    }
  }
  foreach (void a_loopVariable in attributesToRemove) {
    a = a_loopVariable;
    a.Remove();
  }
}

Note: this does not always preserve original attribute order, but I'm sure you could change it to do that pretty easily if it's important to you.

Also note that this also could throw an exception, if you had an XElement attributes that are only unique with the namespace, like:

<root xmlns:ns1="a" xmlns:ns2="b">
    <elem ns1:dupAttrib="" ns2:dupAttrib="" />
</root>

which really seems like an inherent problem. But since the question indicated outputing a String, not an XElement, in this case you could have a solution that would output a valid String that was an invalid XElement.

I also liked jocull's answer using a custom XmlWriter, but when I tried it, it did not work for me. Although it all looks correct, I couldn't tell if the XmlNoNamespaceWriter class had any effect at all; it definitely was not removing the namespaces as I wanted it to.

Empoverish answered 10/10, 2014 at 17:37 Comment(0)
D
1

Adding my that also cleans out the name of nodes that have namespace prefixes:

    public static string RemoveAllNamespaces(XElement element)
    {
        string tex = element.ToString();
        var nsitems = element.DescendantsAndSelf().Select(n => n.ToString().Split(' ', '>')[0].Split('<')[1]).Where(n => n.Contains(":")).DistinctBy(n => n).ToArray();

        //Namespace prefix on nodes: <a:nodename/>
        tex = nsitems.Aggregate(tex, (current, nsnode) => current.Replace("<"+nsnode + "", "<" + nsnode.Split(':')[1] + ""));
        tex = nsitems.Aggregate(tex, (current, nsnode) => current.Replace("</" + nsnode + "", "</" + nsnode.Split(':')[1] + ""));

        //Namespace attribs
        var items = element.DescendantsAndSelf().SelectMany(d => d.Attributes().Where(a => a.IsNamespaceDeclaration || a.ToString().Contains(":"))).DistinctBy(o => o.Value);
        tex = items.Aggregate(tex, (current, xAttribute) => current.Replace(xAttribute.ToString(), ""));

        return tex;
    }
Danette answered 7/5, 2015 at 12:10 Comment(0)
D
1

I tried the first few solutions and didn't work for me. Mainly the problem with attributes 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.HasAttributes ? element.Attributes().Select(a => new XAttribute(a.Name.LocalName, a.Value)) : null,
                        element.HasElements ? element.Elements().Select(e => RemoveAllNamespaces(e)) : null,
                        element.Value);
}
Decennial answered 8/9, 2015 at 8:4 Comment(0)
N
1

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

public static string hilangkanNamespace(string 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;
    }
Nighthawk answered 10/9, 2015 at 4:13 Comment(0)
W
1

This worked for me.

       FileStream fs = new FileStream(filePath, FileMode.Open);

       StreamReader sr = new StreamReader(fs);

        DataSet ds = new DataSet();
        ds.ReadXml(sr);
        ds.Namespace = "";

        string outXML = ds.GetXml();
        ds.Dispose();
        sr.Dispose();
        fs.Dispose();
Wigeon answered 15/3, 2016 at 13:42 Comment(0)
M
0

user892217's answer is almost correct. It won't compile 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 attribute in xmlDocument.Attributes())
    {
        if (!attribute.IsNamespaceDeclaration)
        {
            xElement.Add(attribute);
        }
    }

    return xElement;
}
Metalinguistic answered 17/9, 2013 at 21:46 Comment(0)
I
0

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. Hope this helps someone. (Note: this also removes the SOAP or similar envelope stuff.)

        public static string RemoveNamespaces(string 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
        //
        string 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  (i.e. "<soap" or "<s")
                    int xi = xsXml.Length;
                    string xsChr = "";
                    do
                    {
                        xi--;
                        xsChr = xsXml.Substring(xi, 1);
                        xsXml = xsXml.Substring(0, xi);
                    } while (xsChr != "<");

                    // next, find end of node
                    string xsQt = "";
                    do
                    {
                        xiPos++;
                        if (xiPos <= xiLastPos)
                        {
                            xsChr = psXml.Substring(xiPos, 1);
                            if (xsQt.Length == 0)
                            {
                                if (xsChr == "'" || xsChr == "\"")
                                {
                                    xsQt = xsChr;
                                }
                            }
                            else
                            {
                                if (xsChr == xsQt)
                                {
                                    xsQt = "";  // end of quote
                                }
                                else
                                {
                                    if (xsChr == ">") 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
                            string 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.Substring(0, xiOrgLen - 0);       // first, truncate any added whitespace
                                            // next, peek forward until we find "/" or ">"
                                            string 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);
    }
Ideally answered 28/10, 2016 at 19:9 Comment(0)
B
0

Without recreating whole node hierarchy:

private static void RemoveDefNamespace(XElement element)
{
    var defNamespase = element.Attribute("xmlns");
    if (defNamespase != null)
        defNamespase.Remove();

    element.Name = element.Name.LocalName;
    foreach (var child in element.Elements())
    {
        RemoveDefNamespace(child);
    }
}
Beriberi answered 25/4, 2017 at 13:24 Comment(0)
C
0

I tried some of the solutions, but as stated by so many, there are some edge cases.

Used some of the regexes above, but came to the conclusion that a one step regex is not feasable.

So here is my solution, 2 step regex, find tags, within tags remove, do not alter cdata:

            Func<Match, String> NamespaceRemover = delegate (Match match)
            {
                var result = match.Value;
                if (String.IsNullOrEmpty(match.Groups["cdata"].Value))
                {
                    // find all prefixes within start-, end tag and attributes and also namespace declarations
                    return Regex.Replace(result, "((?<=<|<\\/| ))\\w+:| xmlns(:\\w+)?=\".*?\"", "");
                }
                else
                {
                    // cdata as is
                    return result;
                }
            };
            // XmlDocument doc;
            // string file;
            doc.LoadXml(
              Regex.Replace(File.ReadAllText(file), 
                // find all begin, cdata and end tags (do not change order)
                @"<(?:\w+:?\w+.*?|(?<cdata>!\[CDATA\[.*?\]\])|\/\w+:?\w+)>", 
                new MatchEvaluator(NamespaceRemover)
              )
            );

For now it is 100% working for me.

Common answered 2/4, 2019 at 10:31 Comment(0)
C
0

A vb .net version of Peter Stegnar's code.

Public Class XElementRemoveNameSpace
    '
    'based on
    '  Peter Stegnar's code here
    '   https://mcmap.net/q/186692/-how-to-remove-all-namespaces-from-xml-with-c
    '
    Public Shared Function RemoveAllNamespaces(inXML As XElement) As XElement
        Dim Xel As XElement = _RemoveAllNamespaces(inXML)
        Return Xel
    End Function

    Private Shared Function _RemoveAllNamespaces(inXML As XElement) As XElement
        Dim Xel As XElement
        If Not inXML.HasElements Then
            Xel = New XElement(inXML.Name.LocalName)
            Xel.Value = inXML.Value
            SetAttrs(inXML, Xel)
            Return Xel
        Else
            Xel = New XElement(inXML.Name.LocalName, inXML.Elements().Select(Function(el) _RemoveAllNamespaces(el)))
            SetAttrs(inXML, Xel) 'in case there are attributes on this element
            Return Xel
        End If
    End Function

    Private Shared Sub SetAttrs(inXML As XElement, outXML As XElement)
        If inXML.HasAttributes Then
            Dim nm As String
            Dim NamespaceName As String
            For Each attribute As XAttribute In inXML.Attributes()
                Try
                    nm = attribute.Name.LocalName
                    ' NamespaceName = attribute.Name.NamespaceName 'for debug
                    outXML.SetAttributeValue(nm, attribute.Value) 'stop invOP exception
                Catch invOP As InvalidOperationException
                    'todo dup attributes - should not happen
                Catch ex As Exception
                End Try
            Next
        End If
    End Sub
End Class
Chore answered 29/11, 2022 at 22:9 Comment(0)
E
-1

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;
    }
Expiation answered 17/4, 2013 at 12:59 Comment(0)
E
-1

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

    public string RemoveAllNamespaces(string xmlDocument)
    {
        return Regex.Replace(xmlDocument, @"\sxmlns(\u003A\w+)?\u003D\u0022.+\u0022", " ");
    }
Estellaestelle answered 5/10, 2013 at 9:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.