Namespace Features within the XmlTextWriter

Namespaces are the technique 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 following list shows that the XmlTextWriter has methods that allow an application to declare namespaces in different ways. This includes the ability to:

  • Declare namespaces manually.
  • Override the current namespace declaration with a new namespace.
  • Declare multiple namespaces.

In addition to declaring namespaces, namespace prefixes can be appended to elements and attributes. To write namespace prefixes for attributes, the following methods are used:

  • WriteAttributes
  • WriteAttributeString
  • WriteStartAttribute

For more information on writing prefixes for attributes, see Attribute Namespace Prefixes in the XmlTextWriter.

To write namespace prefixes for elements, the following methods are used:

  • WriteElement
  • WriteElementString
  • WriteStartElement

For more information on writing prefixes for attributes, see Element Namespace Prefixes in the XmlTextWriter.

The writer maintains a namespace stack that tracks the namespaces that have been defined by an element. The following code example shows the use of the namespace stack when writing out elements.

Dim w As New XmlTextWriter(Console.Out)
w.WriteStartElement("root", "urn:1")
w.WriteStartElement("item", "urn:2")
w.WriteEndElement()
w.WriteEndElement()
w.Close()
[C#]
XmlTextWriter w = new XmlTextWriter(Console.Out);
w.WriteStartElement("root","urn:1");
w.WriteStartElement("item","urn:2");
w.WriteEndElement();
w.WriteEndElement(); 
w.Close();

Output

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

The following example shows what happens when a duplicate namespace declaration is used on a nested element. Notice that the empty item element in the output does not repeat the namespace declaration.

Dim w As New XmlTextWriter(Console.Out)
w.WriteStartElement("root", "urn:1")
w.WriteStartElement("item", "urn:1")
w.WriteEndElement()
w.WriteEndElement()
w.Close()
[C#]
XmlTextWriter w = new XmlTextWriter(Console.Out);
w.WriteStartElement("root","urn:1");
w.WriteStartElement("item","urn:1");
w.WriteEndElement();
w.WriteEndElement(); 
w.Close();

Output

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

Manual Namespace Declaration with the XmlTextWriter

Namespace declarations can be written manually, to optimize a number of namespace declarations. The following code example shows how to optimize the number of namespace declarations.

w.WriteStartElement("root")
w.WriteAttributeString("xmlns", "x", Nothing, "urn:1")
w.WriteStartElement("item", "urn:1")
w.WriteEndElement()
w.WriteStartElement("item", "urn:1")
w.WriteEndElement()
w.WriteEndElement()
[C#]
w.WriteStartElement("root");
w.WriteAttributeString("xmlns", "x", null, "urn:1");
w.WriteStartElement("item","urn:1");
w.WriteEndElement();
w.WriteStartElement("item","urn:1");
w.WriteEndElement();
w.WriteEndElement();

Output

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

The preceding code example promoted the namespace declaration to the root element, to avoid having duplicates on the two child elements. The item elements also pick up the prefix from the namespace declaration.

Namespace Declaration Overriding with the XmlTextWriter

The following code example shows how to manually override the namespace associated with a given prefix. Notice that the order value overrides the original namespace URI of 123. This allows the namespace to be redefined in a new element scope.

w.WriteStartElement("x", "node", "123")
w.WriteAttributeString("xmlns", "x", Nothing, "order")
[C#]
w.WriteStartElement("x","node","123");
w.WriteAttributeString("xmlns","x",null,"order");

Output

<x:node xmlns:x="order"/>

Multiple Namespace Declarations with the XmlTextWriter

When there are multiple namespace declarations, mapping different prefixes to the same Uniform Resource Name (URN), the XmlWriter class picks the closest one by going back up the stack of namespace declarations. The following code example shows how the WriteAttributeString specifies no prefix, so that the XmlWriter finds the y prefix first.

Dim w As New XmlTextWriter(Console.Out)
w.WriteStartElement("x", "root", "urn:1")
w.WriteStartElement("y", "item", "urn:1")
w.WriteAttributeString("abc", "urn:1", "xyz")
w.WriteEndElement()
w.WriteEndElement()
w.Close()
[C#]
XmlTextWriter w = new XmlTextWriter(Console.Out);
w.WriteStartElement("x","root","urn:1");
w.WriteStartElement("y","item","urn:1");
w.WriteAttributeString("abc","urn:1","xyz");
w.WriteEndElement();
w.WriteEndElement();
w.Close();

Output

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

See Also

Writing XML with the XmlWriter | Well-Formed XML Creation with the XmlTextWriter | XML Output Formatting with XmlTextWriter | Namespace Features within the XmlTextWriter | Customized XML Writer Creation | XmlTextWriter Class | XmlTextWriter Members | XmlWriter Class | XmlWriter Members