How to remove all namespaces from XML with C#?

前端 未结 30 2218
悲哀的现实
悲哀的现实 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:32

    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();
    
    0 讨论(0)
  • 2020-11-22 13:33

    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;
        }
    
    0 讨论(0)
  • 2020-11-22 13:33

    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;
        }
    
    0 讨论(0)
  • 2020-11-22 13:33

    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;
    }
    
    0 讨论(0)
  • 2020-11-22 13:36

    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));
    }
    
    0 讨论(0)
  • 2020-11-22 13:37

    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, "");
    
    0 讨论(0)
提交回复
热议问题