2008-08-25 6 views
15

J'utilise les technologies .NET XML de manière assez extensive dans mon travail. L'une des choses que j'aime le plus, c'est le moteur XSLT, plus précisément l'extensibilité de celui-ci. Cependant il y a un petit morceau qui continue d'être une source de contrariété. Rien de majeur ou de quelque chose qu'on ne peut pas vivre mais qui nous empêche de produire le magnifique XML que nous aimerions produire. L'une des choses que nous faisons est de transformer les nœuds en ligne et d'importer des nœuds d'un document XML à un autre. Malheureusement, lorsque vous enregistrez des noeuds dans un XmlTextWriter (en fait, quel que soit XmlWriter.Create(Stream) renvoie), les définitions d'espace de noms y sont toutes renvoyées, qu'elles soient nécessaires (définies précédemment) ou non. Vous obtenez le genre de code XML suivant:Gestion correcte de l'espace de noms dans .NET XmlWriter

<root xmlns:abx="http://bladibla"> 
    <abx:child id="A"> 
     <grandchild id="B"> 
      <abx:grandgrandchild xmlns:abx="http://bladibla" /> 
     </grandchild> 
    </abx:child> 
</root> 

Quelqu'un at-il une suggestion quant à la façon de convaincre .NET d'être efficace au sujet de ses définitions d'espace de noms?

Merci, Boaz

PS. En bonus, je voudrais remplacer l'espace de noms par défaut, en le modifiant au fur et à mesure que j'écris un nœud.

Répondre

0

This Ce message pourrait être utile. Jetez également un oeil à Namespaces propriété de XmlTextWriter \ XmlTextReader classes.

+0

'' XmlTextReader' et XmlTextWriter' sont essentiellement amorties, et ne peuvent être utilisés directement si vous travaillez avec les méthodes recommandées 'create'. En tout cas, c'était ici quand j'ai ajouté la prime, alors j'espère que ce n'est pas éligible. Il ne répond pas à la question, qui est parfaitement libellée en tant que telle, * à savoir *, "comment convaincre .NET d'être efficace sur ses définitions d'espace de nommage." J'admets que cela n'est possible que grâce à un lecteur ou un rédacteur personnalisé, mais c'est un hack s'il y a une solution native. – harpo

1

Je ne suis pas sûr que ce soit ce que vous cherchez, mais vous pouvez utiliser ce type de code lorsque vous commencez à écrire au flux Xml:

myWriter.WriteAttributeString("xmlns", "abx", null, "http://bladibla"); 

XmlWriter devrait se rappeler et de ne pas réécrire plus maintenant. Il ne peut pas être 100% à l'épreuve des balles, mais cela fonctionne la plupart du temps.

+0

Il devrait, mais ce n'est pas le cas. Juste pour garder mon pied hors de ma bouche, même si je vais vérifier à nouveau maintenant. – harpo

14

Utilisez ce code:

using (var writer = XmlWriter.Create("file.xml")) 
{ 
    const string Ns = "http://bladibla"; 
    const string Prefix = "abx"; 

    writer.WriteStartDocument(); 

    writer.WriteStartElement("root"); 

    // set root namespace 
    writer.WriteAttributeString("xmlns", Prefix, null, Ns); 

    writer.WriteStartElement(Prefix, "child", Ns); 
    writer.WriteAttributeString("id", "A"); 

    writer.WriteStartElement("grandchild"); 
    writer.WriteAttributeString("id", "B"); 

    writer.WriteElementString(Prefix, "grandgrandchild", Ns, null); 

    // grandchild 
    writer.WriteEndElement(); 
    // child 
    writer.WriteEndElement(); 
    // root 
    writer.WriteEndElement(); 

    writer.WriteEndDocument(); 
} 

Ce code produit souhaité sortie:

<?xml version="1.0" encoding="utf-8"?> 
<root xmlns:abx="http://bladibla"> 
    <abx:child id="A"> 
    <grandchild id="B"> 
     <abx:grandgrandchild /> 
    </grandchild> 
    </abx:child> 
</root> 
+0

Changez cela pour utiliser 'XmlWriter.Create' et je vais l'upvote. –

+0

@John: Fait. Mais quel est le point? Quelles sont les chances? –

+4

@polish: les cotes? Que voulez-vous dire? Le point est que les gens copient/collent nos exemples, et personne ne devrait utiliser 'new XmlTextWriter' à partir de .NET 2.0. –

1

Avez-vous essayé cela?

Dim settings = New XmlWriterSettings With {.Indent = True, 
              .NamespaceHandling = NamespaceHandling.OmitDuplicates, 
              .OmitXmlDeclaration = True} 
Dim s As New MemoryStream 
Using writer = XmlWriter.Create(s, settings) 
    ... 
End Using 

Intéressant est le « » NamespaceHandling.OmitDuplicates

+0

C'est intéressant. Je suis en .NET 2.0, cependant. – harpo

+0

@harpo: Il s'agit de .Net 2.0 (voir http://msdn.microsoft.com/de-de/library/ms162617%28v=vs.80%29.aspx) – habakuk

+0

'XmlWriterSettings' est, mais' NamespaceHandling' la propriété n'est pas. http://msdn.microsoft.com/en-us/library/system.xml.xmlwritersettings.namespacehandling%28v=VS.100%29.aspx – harpo