0

I'm writing a XML document using the XDocument class in C#.

Attempting to get this output:

<Details xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" p2:type="SomeStuff"></Details>

This is what I've tried, but it throws an exception because of the ":"

XNamespace ns = "http://www.w3.org/2001/XMLSchema-instance";

...

new XElement("Details", new XAttribute(XNamespace.Xmlns + "p2", ns), new XAttribute("p2:type", "SomeStuff"),

What is the proper way to achieve the desired output?

dbc
  • 104,963
  • 20
  • 228
  • 340
Quantum_Kernel
  • 303
  • 1
  • 7
  • 19

1 Answers1

3

You must add "type" to the actual namespace URI, "http://www.w3.org/2001/XMLSchema-instance", not to the namespace prefix, like so:

XNamespace ns = "http://www.w3.org/2001/XMLSchema-instance";

var element = new XElement("Details", new XAttribute(ns + "type", "SomeStuff"));

Also, you can completely skip adding an XAttribute for the namespace URI/prefix mapping, XmlWriter will do it automatically as long as XElement.Name.Namespace and XAttribute.Name.Namespace were set correctly during construction.

This is one of the things that makes LINQ to XML simpler than XmlDocument -- you can ignore prefixes entirely and work only with real namespace URIs, which is both simpler and more likely to result in correct code that does not depend on the choice of namespace prefix. Though if you really want to manually specify the prefix for cosmetic reasons see How can I write xml with a namespace and prefix with XElement? which indicates the correct method is:

var element = new XElement("Details", new XAttribute(XNamespace.Xmlns + "p2", ns), new XAttribute(ns + "type", "SomeStuff"));

which results in:

<Details xmlns:p2="http://www.w3.org/2001/XMLSchema-instance" p2:type="SomeStuff" />

Sample .Net fiddle here.

dbc
  • 104,963
  • 20
  • 228
  • 340
  • This seems to produce
    The receiving application has properly interpreted the data anyway.
    – Quantum_Kernel Apr 19 '18 at 07:38
  • @Quantum_Kernel - in that case there was probably an `xmlns:p2="..."` in scope at a higher level. When automatically assigning namespaces `XmlWriter` will add a new prefix rather than redefine one in scope. *The receiving application has properly interpreted the data anyway.* -- good, then it's implemented correctly and parses XML elements according to their actual namespace URI. From [XML namespace](https://en.wikipedia.org/wiki/XML_namespace#Namespaces_in_APIs_and_XML_object_models): *Applications should avoid attaching any significance to the choice of prefix*. – dbc Apr 19 '18 at 07:46