Question

I've encountered an issue whereby when I create an XML Document programmatically using the System.Xml classes and then use the Save method the output XML doesn't use QNames for the Nodes and just uses local names.

eg Desired Output

<ex:root>
  <ex:something attr:name="value">
</ex:root>

But what I currently get is

<root>
  <something name="value">
</root>

This is somewhat simplified since all the Namespaces I'm using are being fully defined using xmlns attributes on the document element but I've omitted that for clarity here.

I'm aware that the XmlWriter class can be used to save an XmlDocument and that this takes an XmlWriterSettings class but I couldn't see how to configure this such that I get full QNames output.

Was it helpful?

Solution

As you say, the root element needs the namespace definition:

<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
    xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
    <iis:WebSite Id="asdf" />
</Wix>

The code for the above xml:

XmlDocument document = new XmlDocument();
document.AppendChild(document.CreateXmlDeclaration("1.0", null, null));
XmlNode rootNode = document.CreateElement("Wix", "http://schemas.microsoft.com/wix/2006/wi");
XmlAttribute attr = document.CreateAttribute("xmlns:iis", "http://www.w3.org/2000/xmlns/");
attr.Value = "http://schemas.microsoft.com/wix/IIsExtension";
rootNode.Attributes.Append(attr);
rootNode.AppendChild(document.CreateElement("iis:WebSite", "http://schemas.microsoft.com/wix/IIsExtension"));
document.AppendChild(rootNode);

The requirement to pass the namespace uri as an argument to the CreateAttribute and CreateElement methods seems counter-intuitive because it could be argued that the document is capable of deriving that information, but hey, that's how it works.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top