How to remove all namespaces from XML with C#?

前端 未结 30 2669
悲哀的现实
悲哀的现实 2020-11-22 13:30

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:

30条回答
  •  清歌不尽
    2020-11-22 13:43

    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

    /// 
    /// Modified XML writer that writes (almost) no namespaces out with pretty formatting
    /// 
    /// 
    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);
    }
    

提交回复
热议问题