How to: Change the Namespace for an Entire XML Tree

You sometimes have to programmatically change the namespace for an element or an attribute. LINQ to XML makes this easy. The System.Xml.Linq.XElement.Name property can be set. The System.Xml.Linq.XAttribute.Name property cannot be set, but you can easily copy the attributes into a System.Collections.Generic.List, remove the existing attributes, and then add new attributes that are in the new desired namespace.

For more information, see Working with XML Namespaces.

Example

The following code creates two XML trees in no namespace. It then changes the namespace of each of the trees, and combines them into a single tree.

XElement tree1 = new XElement("Data",
    new XElement("Child", "content",
        new XAttribute("MyAttr", "content")
    )
);
XElement tree2 = new XElement("Data",
    new XElement("Child", "content",
        new XAttribute("MyAttr", "content")
    )
);
XNamespace aw = "https://www.adventure-works.com";
XNamespace ad = "http://www.adatum.com";
// change the namespace of every element and attribute in the first tree
foreach (XElement el in tree1.DescendantsAndSelf())
{
    el.Name = aw.GetName(el.Name.LocalName);
    List<XAttribute> atList = el.Attributes().ToList();
    el.Attributes().Remove();
    foreach (XAttribute at in atList)
        el.Add(new XAttribute(aw.GetName(at.Name.LocalName), at.Value));
}
// change the namespace of every element and attribute in the second tree
foreach (XElement el in tree2.DescendantsAndSelf())
{
    el.Name = ad.GetName(el.Name.LocalName);
    List<XAttribute> atList = el.Attributes().ToList();
    el.Attributes().Remove();
    foreach (XAttribute at in atList)
        el.Add(new XAttribute(ad.GetName(at.Name.LocalName), at.Value));
}
// add attribute namespaces so that the tree will be serialized with
// the aw and ad namespace prefixes
tree1.Add(
    new XAttribute(XNamespace.Xmlns + "aw", "https://www.adventure-works.com")
);
tree2.Add(
    new XAttribute(XNamespace.Xmlns + "ad", "http://www.adatum.com")
);
// create a new composite tree
XElement root = new XElement("Root",
    tree1,
    tree2
);
Console.WriteLine(root);
Dim tree1 As XElement = _
    <Data>
        <Child MyAttr="content">content</Child>
    </Data>
Dim tree2 As XElement = _
    <Data>
        <Child MyAttr="content">content</Child>
    </Data>
Dim aw As XNamespace = "https://www.adventure-works.com"
Dim ad As XNamespace = "http://www.adatum.com"
' change the namespace of every element and attribute in the first tree
For Each el As XElement In tree1.DescendantsAndSelf
    el.Name = aw.GetName(el.Name.LocalName)
    Dim atList As List(Of XAttribute) = el.Attributes().ToList()
    el.Attributes().Remove()
    For Each at As XAttribute In atList
        el.Add(New XAttribute(aw.GetName(at.Name.LocalName), at.Value))
    Next
Next
' change the namespace of every element and attribute in the second tree
For Each el As XElement In tree2.DescendantsAndSelf()
    el.Name = ad.GetName(el.Name.LocalName)
    Dim atList As List(Of XAttribute) = el.Attributes().ToList()
    el.Attributes().Remove()
    For Each at As XAttribute In atList
        el.Add(New XAttribute(ad.GetName(at.Name.LocalName), at.Value))
    Next
Next
' add attribute namespaces so that the tree will be serialized with
' the aw and ad namespace prefixes
tree1.Add( _
    New XAttribute(XNamespace.Xmlns + "aw", "https://www.adventure-works.com") _
)
tree2.Add( _
    New XAttribute(XNamespace.Xmlns + "ad", "http://www.adatum.com") _
)
' create a new composite tree
Dim root As XElement = _
    <Root>
        <%= tree1 %>
        <%= tree2 %>
    </Root>
Console.WriteLine(root)

This example produces the following output:

<Root>
  <aw:Data xmlns:aw="https://www.adventure-works.com">
    <aw:Child aw:MyAttr="content">content</aw:Child>
  </aw:Data>
  <ad:Data xmlns:ad="http://www.adatum.com">
    <ad:Child ad:MyAttr="content">content</ad:Child>
  </ad:Data>
</Root>

See Also

Other Resources

Modifying XML Trees (LINQ to XML)

Build Date:

2012-08-02