2010-02-25 4 views
2

Si un nœud appartient à un espace de noms, ses enfants appartiennent par défaut au même espace de noms. Il n'est donc pas nécessaire de fournir un attribut xmlns pour chaque enfant, ce qui est bien.LINQ to XML: suppression de l'attribut d'espace de noms redondant dans les nœuds enfants

Cependant.

Si je crée deux nœuds comme celui-ci:

Dim parent = <parent xmlns="http://my.namespace.org"/> 
Dim child = <child xmlns="http://my.namespace.org">value</child> 

parent.Add(child) 

Console.WriteLine(parent.ToString) 

Le résultat est le suivant:

<parent xmlns="http://my.namespace.org"> 
    <child xmlns="http://my.namespace.org">value</child> 
</parent> 

Mais, si les créer d'une manière moins pratique:

Dim parent = <parent xmlns="http://my.namespace.org"/> 
Dim child As New XElement(XName.Get("child", "http://my.namespace.org")) With {.Value = "value"} 

parent.Add(child) 

Console.WriteLine(parent.ToString) 

Le le résultat est plus souhaitable:

<parent xmlns="http://my.namespace.org"> 
    <child>value</child> 
</parent> 

De toute évidence, je préfère utiliser la première méthode parce qu'elle est beaucoup plus intuitive et facile à coder. Il y a aussi une autre raison de ne pas utiliser la méthode 2 - parfois, je dois créer des noeuds avec XElement.Parse, l'analyse d'une chaîne qui contient un attribut xmlns, qui produit exactement les mêmes résultats que la méthode 1.

La question est - comment faire Je reçois la jolie sortie de la méthode 2, créant des noeuds comme dans la méthode 1? La seule option que je vois est de créer une méthode qui clonerait XElement donné, en le recréant efficacement selon le modèle de la méthode 2, mais cela semble moche. Je cherche une solution plus évidente que j'ai oubliée pour une raison quelconque.

+0

@GSerg: Est-ce que la réponse ci-dessous répond à votre question? –

Répondre

1

Ugh ... namespaces - ils seront la mort de moi.

Ici, vous allez:

Dim ns As XNamespace = "http://my.namespace.org" 
Dim parent = <<%= ns + "parent" %>/> 
Dim child = <<%= ns + "child" %>>value</> 
parent.Add(child) 

Pour pouvoir utiliser XElement.Parse et de garder les nœuds enfants en phase avec les espaces de noms de leurs nœuds parents, il est préférable d'utiliser les espaces de noms mondiaux. Vraiment facile à faire dans VB.NET. En haut de votre module/classe, utilisez simplement une importation et tous les parents et enfants utiliseront cet espace de noms. Par exemple:

Imports <xmlns="http://my.namespace.org"> 
Module Main 
    Sub SomeSub() 
     Dim child = <child>value</child> 
     Dim parent = <parent><%= child %></parent> 
     Console.WriteLine(parent.ToString) 
    End Sub 
End Module 

Notez que l'élément <child/> est créé en premier. La même chose s'appliquerait à un espace de noms autre que par défaut, tel que Imports <xmlns:p="http://parent.namespace.org">, puis créerait avec <p:child/> et <p:parent/>.

Une fois, j'ai lu, mais je n'ai pas encore trouvé, que mélanger des littéraux XML avec I-ne-sais-pas-que-vous-appelez-mais-c'est-parent.Add(something)-quoi que ce soit est une mauvaise idée.

+0

C'est un super truc! Un peu brouillon dans les littéraux, mais la sortie est plus propre. – CoderDennis

+0

L'astuce est bien en effet, mais elle ne résout que partiellement le problème. Si j'ai une chaîne XML que j'analyse, la sortie contient des espaces de noms pour les nœuds enfants. Donc, je cherchais un moyen de définir une sorte de je-ne-veux-pas-ce drapeau contre un nœud déjà construit plutôt que d'une manière spéciale de construire un nœud - parce que je ne peux pas utiliser cette façon spéciale parfois. Pourtant, je suis heureux d'accepter cette réponse si aucune autre solution n'existe. – GSerg

+0

@GSerg: Ah, je comprends maintenant. J'ai mis à jour la réponse avec ce que je souhaite travailler pour vous. –