Recently, I got a requirement to generate an XML on the fly with some defined schema. I know this requirement looks very simple at first sight, but actually, it was not.
The XML that was to be generated had a very specific format as it was supposed to be the input for some third-party tools. So, it means, it should be fully compliant with the prescribed XML node structure. Just have a look at the below schema.
<sl:RandomWindow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sl="http://www.ShwetaBlogs.com/Window"
xsi:schemaLocation="http://www.ShwetaBlogs.com/Window wwRandomWindow.xsd">
<Title>First Window</Title>
<Border>Single</Border>
</sl:RandomWindow>
Below are the classes I created for serialization purposes.
public class RandomWindow
{
[XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string schemaLocation { get; set; }
[XmlElement]
public string Title { get; set; }
[XmlElement]
public string Border { get; set; }
}
By using the XmlElement and XmlAttribute classes, I was able to generate most of the required parts of the XML, as shown below.
<?xml version="1.0" encoding="UTF-8"?>
<RandomWindow xsi:schemaLocation="http://www.ShwetaBlogs.com/Window wwRandomWindow.xsd"
xmlns:sl="http://www.ShwetaBlogs.com/Window"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Title>First Window</Title>
<Border>Single</Border>
</RandomWindow>
But the only thing that didn’t come up correctly was the root node that is expected to be in the form <sl: RandomWindow>.
So, to achieve the root node with prefix and colon, I updated the code.
[XmlRoot("sl:RandomWindow")]
public class RandomWindow { ... }
But alas! It gave me some strange results. It converted the prefix to hexadecimal, as shown below. Then I thought, instead of providing a concrete prefix, let’s add namespace itself.
[XmlRoot("RandomWindow", Namespace = "http://www.ShwetaBlogs.com/Window")]
public class RandomWindow { ...}
And my result was a bit closer to what I needed, but not the exact one. Now, the issue remaining was the extra prefix in front of each element :(.
To resolve this issue, I tried various options provided by various blogs, but no luck. However, after spending hours, I was able to crack it with a "hit and try" formula. To hide namespaces at the element node level, I provided the namespace value as empty just like in the code shown below.
[XmlRoot("RandomWindow", Namespace = "http://www.ShwetaBlogs.com/Window")]
public class RandomWindow
{
[XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string schemaLocation { get; set; }
[XmlElement(Namespace = " ")]
public string Title { get; set; }
[XmlElement(Namespace = " ")]
public string Border { get; set; }
}
And that did the trick for me. Finally, I was able to achieve the required format.
<?xml version="1.0" encoding="UTF-8"?>
<sl:RandomWindow xsi:schemaLocation="http://www.ShwetaBlogs.com/Window wwRandomWindow.xsd"
xmlns:sl="http://www.ShwetaBlogs.com/Window"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Title xmlns=" ">First Window</Title>
<Border xmlns=" ">Single</Border>
</sl:RandomWindow>
Although this issue was pretending to be very small, it ate up so much of my time. This is why I thought to share it here in hopes that it would be helpful for you and would save you time.
Happy troubleshooting !!!