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 which was to be generated was having 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 which didn’t come up correctly was the root node that is expected to be in the form <sl:RandomWindow>.
So, in order to achieve the root node with prefix and colon, I updated the code to -
- [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 need, but not the exact one. Now, the issue remaining was the extra prefix in front of each element :(.
In order 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 by a "hit and try" formula. To hide namespaces at 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 will save your time.
Happy troubleshooting !!!