Search code examples
c#xmllinq-to-xml

How to replace xmlns inside xml with C#


I tried to replace xmlns version (any version) with version http://schemas.telerik.com/reporting/2012/3.6. inside C# project

This what I get as input.

<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="http://schemas.telerik.com/reporting/2012/4.0" 
        SnapGridSize="0.1cm" ShowSnapGrid="True" Name="NoviUgovor" Width="18.462cm">
</Report>

Input xmlns version of Telerik reporting is changeable.

And this is what I am trying to get:

<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="http://schemas.telerik.com/reporting/2012/3.6" 
        SnapGridSize="0.1cm" ShowSnapGrid="True" Name="NoviUgovor" Width="18.462cm">
</Report>

Output xmlns version of Telerik reporting has to be

http://schemas.telerik.com/reporting/2012/3.6

This is the code inside the project:

var doc = XDocument.Parse(rpt_dok);//rpt_dok (xml)
doc.Root.Attributes().Where(x => x.IsNamespaceDeclaration).Remove();
doc.Root.Add(new XAttribute("xmlns", "http://schemas.telerik.com/reporting/2012/3.6"));
rpt_dok = doc.ToString(); //error appears

I got error:

Additional information: The prefix '' cannot be redefined from 'http://schemas.telerik.com/reporting/2012/4.0' to 'http://schemas.telerik.com/reporting/2012/3.6' within the same start element tag.

I have tried https://dotnetfiddle.net/qFuwWk but with no luck.

Any help please!


Solution

  • To change xmlns is quite tricky. You need to replace the whole node. I think the simpliest and the most reliable way is to fix a text of xml

    rpt_dok = rpt_dok.Replace("http://schemas.telerik.com/reporting/2012/4.0", 
                                 "http://schemas.telerik.com/reporting/2012/3.6");
    

    or if you don't know what version you have, you need to get the version string at first

    var doc = XDocument.Parse(rpt_doc); //rpt_dok (xml)
    string xmlns= doc.Root.Attributes().Where(x => x.IsNamespaceDeclaration).First().Value;
    rpt_dok = rpt_dok.Replace(xmlns, "http://schemas.telerik.com/reporting/2012/3.6");
    
    doc = XDocument.Parse(rpt_doc)
    ... your code
    

    and your fiddle example

    string xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
                                 <Main version=""1.0"" xmlns=""urn:root:v1"">
                                     <Report>
                                         <Title>Some Value</Title>
                                     </Report>
                                     <Content>
                                         <Address>
                                             <CountryName xmlns=""urn:location:v2"">Australia</CountryName>
                                         </Address>
                                     </Content>
                                 </Main>";
    
        var doc = XDocument.Parse(xml);
    
        var xmlns = doc.Descendants().Attributes()
                                     .Where(x => x.IsNamespaceDeclaration)
                                     .Select(x => x.ToString());
        
        foreach (var ns in xmlns)
        {
            if (ns.Contains("root"))
                xml = xml.Replace(ns, ns.Replace("xmlns", "xmlns:root"));
            else if (ns.Contains("location"))
                xml = xml.Replace(ns, ns.Replace("xmlns", "xmlns:loc"));
        }
    
        doc = XDocument.Parse(xml);
        Console.WriteLine(doc);