locked
XDocument remove namespace RRS feed

  • Question

  • Hi,

    does anybody know how to remove the namespace of a XML loaded into XDocument object? I already tried removing all attributes or the xmlns attribute only but looks like it's read-only.

    Thanks,

    Tom
    Wednesday, January 9, 2008 10:54 PM

Answers

  • Hi Tom,

     

    As I understand, you can't remove namespace for XmlDocument in-memory. Namespace is integral part of name, so you have to recreate any element, which is in the namespace. Alternatively strip namespaces while writing XmlDocument out using some custom XmlWriter, try to look into this blog for details - http://blogs.msdn.com/kaevans/archive/2004/08/02/206432.aspx

    Besides, you can try to remove XML namespace using regular expression as the following sample codes and see if it works on your side:

    Code Block

    XmlDocument stripDocumentNamespace(XmlDocument oldDom)
    {
    // Remove all xmlns:* instances from the passed XmlDocument
    // to simplify our xpath expressions.
    XmlDocument newDom = new XmlDocument();
    newDom.LoadXml(System.Text.RegularExpressions.Regex.Replace(
    oldDom.OuterXml, @"(xmlns:?[^=]*=[""][^""]*[""])", "",
    System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Multiline)
    );
    return newDom;
    }

     

    This one gets rid of all "xmlns:{alias}" occurencies in the document, but you can limit it by making the Regex more restrictive if needed. Try to check out this blog for more details - http://www.pluralsight.com/blogs/keith/archive/2005/10/19/15714.aspx

     

    hope this helps,

    Regards,

    Friday, January 11, 2008 4:07 AM
  • If you'd like to process an XML document as if the "Namespaces in XML 1.0" specification doesn't have any impact on the data model, you can apply an in-place transformation on the document that not only removes all the namespace declarations but also moves all element and attribute names into XNamespace.None. I'm not sure why you would like that but it's certainly possible with LINQ to XML:

     

    Code Block
    static void Main() {
        XElement root = XElement.Parse(@"
    <root xmlns='default namespace'>
        <e p:a='value' xmlns:p='p namespace' b='value'/>
        <q:f xmlns:q='q namespace'/>
    </root>
    ");
        foreach (XElement e in root.DescendantsAndSelf()) {
            if (e.Name.Namespace != XNamespace.None) {
                e.Name = XNamespace.None.GetName(e.Name.LocalName);
            }
            if (e.Attributes().Where(a => a.IsNamespaceDeclaration || a.Name.Namespace != XNamespace.None).Any()) {
                e.ReplaceAttributes(e.Attributes().Select(a => a.IsNamespaceDeclaration ? null : a.Name.Namespace != XNamespace.None ? new XAttribute(XNamespace.None.GetName(a.Name.LocalName), a.Value) : a));
            }
        }
        Console.WriteLine(root);
        Console.WriteLine(root.Element("e").Attribute("a"));
    }

     

     

    Ion

     

    Friday, January 11, 2008 6:38 PM

All replies

  • Hi Tom,

     

    As I understand, you can't remove namespace for XmlDocument in-memory. Namespace is integral part of name, so you have to recreate any element, which is in the namespace. Alternatively strip namespaces while writing XmlDocument out using some custom XmlWriter, try to look into this blog for details - http://blogs.msdn.com/kaevans/archive/2004/08/02/206432.aspx

    Besides, you can try to remove XML namespace using regular expression as the following sample codes and see if it works on your side:

    Code Block

    XmlDocument stripDocumentNamespace(XmlDocument oldDom)
    {
    // Remove all xmlns:* instances from the passed XmlDocument
    // to simplify our xpath expressions.
    XmlDocument newDom = new XmlDocument();
    newDom.LoadXml(System.Text.RegularExpressions.Regex.Replace(
    oldDom.OuterXml, @"(xmlns:?[^=]*=[""][^""]*[""])", "",
    System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Multiline)
    );
    return newDom;
    }

     

    This one gets rid of all "xmlns:{alias}" occurencies in the document, but you can limit it by making the Regex more restrictive if needed. Try to check out this blog for more details - http://www.pluralsight.com/blogs/keith/archive/2005/10/19/15714.aspx

     

    hope this helps,

    Regards,

    Friday, January 11, 2008 4:07 AM
  • If you'd like to process an XML document as if the "Namespaces in XML 1.0" specification doesn't have any impact on the data model, you can apply an in-place transformation on the document that not only removes all the namespace declarations but also moves all element and attribute names into XNamespace.None. I'm not sure why you would like that but it's certainly possible with LINQ to XML:

     

    Code Block
    static void Main() {
        XElement root = XElement.Parse(@"
    <root xmlns='default namespace'>
        <e p:a='value' xmlns:p='p namespace' b='value'/>
        <q:f xmlns:q='q namespace'/>
    </root>
    ");
        foreach (XElement e in root.DescendantsAndSelf()) {
            if (e.Name.Namespace != XNamespace.None) {
                e.Name = XNamespace.None.GetName(e.Name.LocalName);
            }
            if (e.Attributes().Where(a => a.IsNamespaceDeclaration || a.Name.Namespace != XNamespace.None).Any()) {
                e.ReplaceAttributes(e.Attributes().Select(a => a.IsNamespaceDeclaration ? null : a.Name.Namespace != XNamespace.None ? new XAttribute(XNamespace.None.GetName(a.Name.LocalName), a.Value) : a));
            }
        }
        Console.WriteLine(root);
        Console.WriteLine(root.Element("e").Attribute("a"));
    }

     

     

    Ion

     

    Friday, January 11, 2008 6:38 PM
  • Hi friend,

     

    I was facing the same issue and i was able to fix it.

     

    It is as simple as that.

     

    The parent Node would obiviously have an xmlns argument as it was created. May if the parent node does not have it just check the immediate parent. Just give the xmlns argument given to the parent elements as you start creating new nodes under the parent element. It would create the node without the xmlns argument.

     

    Regards

    Harikrishnan

     

    Monday, September 22, 2008 8:42 AM
  • Hi friends,

     

    I have generated an xml and cannocialised it. Then a portion of the xml is extracted to generate a security code that acts as the input value of a tag in the same xml that is inserted subsequently in the same xml.

     

    But by means of validation it has been identified that the value computed is wrong.

     

    So can anyone please help me with the code that cannocialises a part of the xml and generates the encrypted value of the body of the xml using the SHA1 algorithm.

     

    I have tried the whole thing using the references given here but it has been identified as generating an incorrect value.

     

    Regards

    Harikrishnan

     

    Monday, September 22, 2008 10:46 AM
  • XDocument doc = XDocument.Load(filePath, LoadOptions.PreserveWhitespace);
    doc.Descendants().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
    doc.Save(filePath, SaveOptions.DisableFormatting);

    Greg
    Thursday, November 25, 2010 12:27 AM
  • doc.Descendants().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
    Perfect! Just what I was looking for!

    Friday, August 26, 2011 6:49 PM
  • It doesn't work when I use the code:
    XDocument doc = XDocument.Load(filePath, LoadOptions.PreserveWhitespace);
    doc.Descendants().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
    doc.Save(filePath, SaveOptions.DisableFormatting);
    my output xml code still remain a mark of namespace "xmlns".
    is there any other parameters should notice? Help me!
    • Proposed as answer by Anon User 1 Monday, November 28, 2011 3:54 PM
    • Unproposed as answer by Anon User 1 Monday, November 28, 2011 3:55 PM
    Friday, September 2, 2011 2:08 AM
  • XElement doc = XElement.Parse(ToXml());
    doc.DescendantsAndSelf().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
    var ele = doc.DescendantsAndSelf();
    foreach (var el in ele)
        el.Name = el.Name.LocalName;
    
    

    Works for me!

    Monday, November 28, 2011 4:02 PM
  • XElement doc = XElement.Parse(ToXml());
    doc.DescendantsAndSelf().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
    var ele = doc.DescendantsAndSelf();
    foreach (var el in ele)
        el.Name = el.Name.LocalName;
    
    

    Works for me!


    This works for me too! Thank you!
    Wednesday, July 11, 2012 2:57 AM