Pergunta

Ao gerar XML de XmlDocument em NET, um atributo xmlns branco aparece pela primeira vez, um elemento sem um espaço de nomes associados é inserido; como isso pode ser evitado?

Exemplo:

XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root",
    "whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner"));
Console.WriteLine(xml.OuterXml);

Output:

<root xmlns="whatever:name-space-1.0"><loner xmlns="" /></root>

desejado de saída:

<root xmlns="whatever:name-space-1.0"><loner /></root>

Existe uma solução aplicável ao código XmlDocument, não é algo que ocorre após converter o documento para uma string com OuterXml?

Meu raciocínio para fazer isso é para ver se eu pode coincidir com o XML padrão de um protocolo especial usando XML XmlDocument gerado. O atributo em branco xmlns pode não quebrar ou confundir um parser, mas também não está presente em qualquer uso que eu vi do presente protocolo.

Foi útil?

Solução

Graças a resposta de Jeremy Lew e um pouco mais de brincar, eu descobri como remover em branco atributos xmlns: passagem no espaço de nomes do nó raiz ao criar qualquer nó filho que você quer não ter um prefixo em. Usando um namespace sem um prefixo para os meios de raiz que você precisa usar essa mesma namespace em elementos filhos para eles também não tem prefixos.

Código Fixo:

XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root", "whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner", "whatever:name-space-1.0")); 
Console.WriteLine(xml.OuterXml);

Obrigado a todos para todas as suas respostas que me levou na direção certa!

Outras dicas

Esta é uma variante da resposta de JeniT (Obrigado muito muito btw!)

XmlElement new_element = doc.CreateElement("Foo", doc.DocumentElement.NamespaceURI);

Este elimina a necessidade de copiar ou repetir o namespace em todos os lugares.

Se o elemento <loner> em sua XML amostra não tem a declaração de namespace xmlns padrão sobre ele, então seria no namespace whatever:name-space-1.0 em vez de ser em nenhum namespace. Se é isso que você quer, você precisa criar o elemento em que namespace:

xml.CreateElement("loner", "whatever:name-space-1.0")

Se você deseja que o elemento <loner> ser em nenhum namespace, então o XML que foi produzido é exatamente o que você precisa, e você não deve se preocupar com o atributo xmlns que foi adicionado automaticamente para você.

Desde raiz está em um namespace unprefixed, qualquer criança de raiz que quer ser un-namespaced tem que ser uma saída como seu exemplo. A solução seria para prefixar o elemento raiz assim:

<w:root xmlns:w="whatever:name-space-1.0">
   <loner/>
</w:root>

código:

XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement( "w", "root", "whatever:name-space-1.0" );
doc.AppendChild( root );
root.AppendChild( doc.CreateElement( "loner" ) );
Console.WriteLine(doc.OuterXml);

Se possível, crie uma classe de serialização, em seguida, fazer:

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer serializer = new XmlSerializer(yourType);
serializer.Serialize(xmlTextWriter, someObject, ns);

É mais seguro, e você pode controlar os espaços de nomes com atributos se você realmente precisa de mais controle.

Eu já resolveu o problema usando o padrão de fábrica. Eu criei uma fábrica para objetos XElement. Como parâmetro para a instanciação da fábrica eu tenha especificado um objeto XNamespace. Então, toda vez que um XElement é criado pela fábrica o namespace será adicionado automaticamente. Aqui está o código da fábrica:

internal class XElementFactory
{
    private readonly XNamespace currentNs;

    public XElementFactory(XNamespace ns)
    {
        this.currentNs = ns;
    }

    internal XElement CreateXElement(String name, params object[] content)
    {
        return new XElement(currentNs + name, content);
    }
}

Sim, você pode impedir que os XMLNS do XmlElement. Primeiro Criação de tempo que está chegando: como aquele

<trkpt lat="30.53597" lon="-97.753324" xmlns="">
    <ele>249.118774</ele>
    <time>2006-05-05T14:34:44Z</time>
</trkpt>

Alterar o código: E namespace passagem xml como esta

C # código:

XmlElement bookElement = xdoc.CreateElement("trkpt", "http://www.topografix.com/GPX/1/1");
bookElement.SetAttribute("lat", "30.53597");
bookElement.SetAttribute("lon", "97.753324");
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top