LinqToXML removing empty xmlns attributes & adding attributes like xmlns:xsi, xsi:schemaLocation
- by Rohit Gupta
Suppose you need to generate the following XML: 1: <GenevaLoader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2: xsi:schemaLocation="http://www.advent.com/SchemaRevLevel401/Geneva masterschema.xsd"
3: xmlns="http://www.advent.com/SchemaRevLevel401/Geneva">
4: <PriceRecords>
5: <PriceRecord>
6: </PriceRecord>
7: </PriceRecords>
8: </GenevaLoader>
Normally you would write the following C# code to accomplish this:
1: const string ns = "http://www.advent.com/SchemaRevLevel401/Geneva";
2: XNamespace xnsp = ns;
3: XNamespace xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
4:
5: XElement root = new XElement( xnsp + "GenevaLoader",
6: new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName),
7: new XAttribute( xsi + "schemaLocation", "http://www.advent.com/SchemaRevLevel401/Geneva masterschema.xsd"));
8:
9: XElement priceRecords = new XElement("PriceRecords");
10: root.Add(priceRecords);
11:
12: for(int i = 0; i < 3; i++)
13: {
14: XElement price = new XElement("PriceRecord");
15: priceRecords.Add(price);
16: }
17:
18: doc.Save("geneva.xml");
The problem with this approach is that it adds a additional empty xmlns arrtribute on the “PriceRecords” element, like so :
1: <GenevaLoader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.advent.com/SchemaRevLevel401/Geneva masterschema.xsd" xmlns="http://www.advent.com/SchemaRevLevel401/Geneva">
2: <PriceRecords xmlns="">
3: <PriceRecord>
4: </PriceRecord>
5: </PriceRecords>
6: </GenevaLoader>
The solution is to add the xmlns NameSpace in code to each child and grandchild elements of the root element like so :
1: XElement priceRecords = new XElement( xnsp + "PriceRecords");
2: root.Add(priceRecords);
3:
4: for(int i = 0; i < 3; i++)
5: {
6: XElement price = new XElement(xnsp + "PriceRecord");
7: priceRecords.Add(price);
8: }