Namespace Handling in the XmlWriter

Namespaces are used to qualify element and attribute names in an XML document. Namespace prefixes associate elements and attributes with namespaces, which are in turn associated to a URI reference. Namespaces create element and attribute name uniqueness in an XML document.

The XmlWriter maintains a namespace stack corresponding to all the namespaces defined in the current namespace scope. When writing elements and attributes you can utilize namespaces in the following ways:

  • Declare namespaces manually.

  • Override the current namespace declaration with a new namespace.

  • Specify a namespace prefix when writing attributes or elements.

Declare Namespaces Manually

Namespace declarations can be written out manually using the WriteAttributeString method. This can be useful when you know how to best optimize the number of namespace declarations. In the following code a namespace declaration is created on the root element.

writer.WriteStartElement("root")
writer.WriteAttributeString("xmlns", "x", Nothing, "urn:1")
writer.WriteStartElement("item", "urn:1")
writer.WriteEndElement()
writer.WriteStartElement("item", "urn:1")
writer.WriteEndElement()
writer.WriteEndElement()
writer.WriteStartElement("root");
writer.WriteAttributeString("xmlns", "x", null, "urn:1");
writer.WriteStartElement("item", "urn:1");
writer.WriteEndElement();
writer.WriteStartElement("item", "urn:1");
writer.WriteEndElement();
writer.WriteEndElement();

The code generates the following XML string.

<root xmlns:x="urn:1">
  <x:item/>
  <x:item/>
</root>

Because the namespace declaration is on the root element, it is not duplicated on the two child elements. The item elements also pick up the prefix from the namespace declaration.

Override Current Namespaces

It is possible to manually override the namespace associated with a given prefix. In the following code, the namespace URI for the "x" prefix is changed from "123" to "abc".

writer.WriteStartElement("x", "root", "123")
writer.WriteStartElement("item")
writer.WriteAttributeString("xmlns", "x", Nothing, "abc")
writer.WriteEndElement()
writer.WriteEndElement()
writer.WriteStartElement("x", "root", "123");
writer.WriteStartElement("item");
writer.WriteAttributeString("xmlns", "x", null, "abc");
writer.WriteEndElement();
writer.WriteEndElement();

The code generates the following XML string:

<x:root xmlns:x="123">
  <item xmlns:x="abc" />
</x:root>

Specify a Namespace Prefix

You can also pass the namespace prefix to use by explicitly specifying a prefix when writing an element or attribute. Many of the methods used to write element and attributes allow you to specify a namespace prefix. The following code shows how to specify a prefix when writing an element.

writer.WriteStartElement("x", "root", "urn:1")
writer.WriteStartElement("y", "item", "urn:1")
writer.WriteEndElement()
writer.WriteEndElement()
writer.WriteStartElement("x", "root", "urn:1");
writer.WriteStartElement("y", "item", "urn:1");
writer.WriteEndElement();
writer.WriteEndElement();

The code writes the following XML string:

<x:root xmlns:x="urn:1">
  <y:item xmlns:y="urn:1"/>
</x:root>

The XmlWriter preserves both prefixes, "x" and "y".

Note

All XmlWriter implementations, including XmlTextWriter, allow the namespace to be empty when a prefix is supplied. In this case, the writer ignores the prefix. This is a change in behavior in the Microsoft .NET Framework version 2.0 release. In previous versions, this condition results in an XmlException being thrown.

See Also

Other Resources

Writing XML with the XmlWriter