Como criar um documento com namespaces em C# (LINQ to XML)

Este artigo mostra como criar documentos em C# que tenham namespaces.

Exemplo: declarar e inicializar um namespace padrão

Para criar um elemento ou um atributo que esteja em um namespace, você primeiro declara e inicializa um objeto XNamespace. Em seguida, você usa a sobrecarga do operador de adição para combinar o namespace com o nome local, expresso como uma cadeia de caracteres.

O exemplo a seguir cria um documento com um namespace. Por padrão, o LINQ to XML serializa esse documento com um namespace padrão.

// Create an XML tree in a namespace.
XNamespace aw = "http://www.adventure-works.com";
XElement root = new XElement(aw + "Root",
    new XElement(aw + "Child", "child content")
);
Console.WriteLine(root);

Esse exemplo gera a saída a seguir:

<Root xmlns="http://www.adventure-works.com">
  <Child>child content</Child>
</Root>

Exemplo: criar um documento que tenha um namespace e um atributo

O exemplo a seguir cria um documento com um namespace. Também cria um atributo que declara o namespace com um prefixo de namespace. Para criar um atributo que declare um namespace com um prefixo, você cria um atributo onde o namespace do nome do atributo seja o prefixo do namespace, e esse nome esteja no namespace Xmlns. O valor desse atributo é o URI do namespace.

// Create an XML tree in a namespace, with a specified prefix
XNamespace aw = "http://www.adventure-works.com";
XElement root = new XElement(aw + "Root",
    new XAttribute(XNamespace.Xmlns + "aw", "http://www.adventure-works.com"),
    new XElement(aw + "Child", "child content")
);
Console.WriteLine(root);

Esse exemplo gera a saída a seguir:

<aw:Root xmlns:aw="http://www.adventure-works.com">
  <aw:Child>child content</aw:Child>
</aw:Root>

Exemplo: criar um documento que tenha dois namespaces, um deles com prefixo

O exemplo a seguir mostra a criação de um documento que contém dois namespaces. Um é o namespace padrão, o outro é um namespace com um prefixo.

Com a inclusão de atributos de namespace no elemento raiz, os namespaces são serializados, de modo que http://www.adventure-works.com seja o namespace padrão e www.fourthcoffee.com seja serializado com o prefixo fc. Para criar um atributo que declare um namespace padrão, você cria um atributo com o nome xmlns, sem um namespace. O valor do atributo é o URI padrão do namespace.

// The http://www.adventure-works.com namespace is forced to be the default namespace.
XNamespace aw = "http://www.adventure-works.com";
XNamespace fc = "www.fourthcoffee.com";
XElement root = new XElement(aw + "Root",
    new XAttribute("xmlns", "http://www.adventure-works.com"),
    new XAttribute(XNamespace.Xmlns + "fc", "www.fourthcoffee.com"),
    new XElement(fc + "Child",
        new XElement(aw + "DifferentChild", "other content")
    ),
    new XElement(aw + "Child2", "c2 content"),
    new XElement(fc + "Child3", "c3 content")
);
Console.WriteLine(root);

Esse exemplo gera a saída a seguir:

<Root xmlns="http://www.adventure-works.com" xmlns:fc="www.fourthcoffee.com">
  <fc:Child>
    <DifferentChild>other content</DifferentChild>
  </fc:Child>
  <Child2>c2 content</Child2>
  <fc:Child3>c3 content</fc:Child3>
</Root>

Exemplo: Criar um documento que tenha dois namespaces, ambos com prefixos

O exemplo a seguir cria um documento que contém dois namespaces, ambos com prefixos de namespace.

XNamespace aw = "http://www.adventure-works.com";
XNamespace fc = "www.fourthcoffee.com";
XElement root = new XElement(aw + "Root",
    new XAttribute(XNamespace.Xmlns + "aw", aw.NamespaceName),
    new XAttribute(XNamespace.Xmlns + "fc", fc.NamespaceName),
    new XElement(fc + "Child",
        new XElement(aw + "DifferentChild", "other content")
    ),
    new XElement(aw + "Child2", "c2 content"),
    new XElement(fc + "Child3", "c3 content")
);
Console.WriteLine(root);

Esse exemplo gera a saída a seguir:

<aw:Root xmlns:aw="http://www.adventure-works.com" xmlns:fc="www.fourthcoffee.com">
  <fc:Child>
    <aw:DifferentChild>other content</aw:DifferentChild>
  </fc:Child>
  <aw:Child2>c2 content</aw:Child2>
  <fc:Child3>c3 content</fc:Child3>
</aw:Root>

Exemplo: criar um namespace usando nomes expandidos

Outra maneira de obter o mesmo resultado é usar nomes expandidos, em vez de declarar e criar um objeto XNamespace.

Essa abordagem tem implicações de desempenho. Cada vez que você passa uma cadeia de caracteres que contém um nome expandido para o LINQ to XML, o LINQ to XML deve analisar o nome, localizar o namespace atomizado e localizar o nome atomizado. Esse processo utiliza tempo de CPU. Se o desempenho for importante, convém declarar e usar um objeto XNamespace explicitamente.

Se o desempenho for uma questão importante, confira Pré-atomização de objetos XName para obter mais informações.

// Create an XML tree in a namespace, with a specified prefix
XElement root = new XElement("{http://www.adventure-works.com}Root",
    new XAttribute(XNamespace.Xmlns + "aw", "http://www.adventure-works.com"),
    new XElement("{http://www.adventure-works.com}Child", "child content")
);
Console.WriteLine(root);

Esse exemplo gera a saída a seguir:

<aw:Root xmlns:aw="http://www.adventure-works.com">
  <aw:Child>child content</aw:Child>
</aw:Root>

Confira também