2009-06-22 3 views
4

J'ai une exigence pour faire un fichier XML - et le partenaire est plutôt collant sur l'en-tête. Apparemment, l'en-tête doit être exactement ceci:VB.NET XMLWriter: Comment changer le contenu de l'en-tête?

<?xml version="1.0"?> 

Mais chaque fois que je crée un fichier XML j'obtenir des propriétés étrangères comme ceci:

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 

Le pirate en moi veut cesser d'utiliser XMLWriter pour rendre le fichier de sorte que j'ai plus de contrôle sur l'en-tête; "pas de problème, je vais juste écrire une boucle qui fait ses propres balises XML comme un StreamWriter ou quelque chose, oubliez cet objet XMLWriter ..." mais je dois admettre que XMLWriter a été plutôt élégant à utiliser jusqu'à présent; il doit sûrement y avoir quelque chose où je peux changer l'objet XMLWriterSettings pour dire "arrête de mettre vos propriétés personnalisées dans l'entête XML s'il vous plait", n'est-ce pas?

Voici le code VB concerné:

Dim settings As New XmlWriterSettings() 
    settings.Indent = True 
    settings.IndentChars = " " 
    settings.NewLineChars = "\n" 
    Using writer As XmlWriter = XmlWriter.Create(strFileName, settings) 
      writer.WriteStartDocument(True) 
      For Each kvp As KeyValuePair(Of String, String) In dictArguments 

       Dim key As String = kvp.Key 
       Dim value As String = kvp.Value 

       writer.WriteStartElement(key) 
       writer.WriteString(value) 
       writer.WriteEndElement() 

      Next 

    End Using 

fonctionne parfaitement; mais je ne peux pas trouver un moyen de contrôler l'en-tête. Je peux trouver un moyen de l'enlever complètement bien sûr, mais ce n'est pas ce que nous voulons faire.

Modifier: merci pour l'aide; jusqu'à présent, une fois que nous avons supprimé le WriteStartDocument, il n'a plus d'affichage standalone = yes. Je ne peux pas l'obtenir pour arrêter d'ajouter l'encodage cependant. Des idées?

Répondre

10

Une façon de le faire est de prendre le contrôle de l'instruction de traitement initiale vous avec la méthode WriteProcessingInstruction ainsi:

Dim settings As New XmlWriterSettings() 
    settings.Indent = True 
    settings.IndentChars = " " 
    Using writer As XmlWriter = XmlWriter.Create(strFileName, settings) 
     writer.WriteProcessingInstruction("xml", "version='1.0'") 
     writer.WriteStartElement("root") 
     For Each kvp As KeyValuePair(Of String, String) In dictArguments 

      Dim key As String = kvp.Key 
      Dim value As String = kvp.Value 

      writer.WriteStartElement(key) 
      writer.WriteString(value) 
      writer.WriteEndElement() 

     Next 
     writer.WriteEndElement() 

    End Using 

Notez que j'ai également ajouté un élément « racine » dans le cas où votre dictionnaire contient plus qu'un élément (et je devine qu'aucune des valeurs clés du dictionnaire n'est "root" :)

+0

excellent merci! –

+0

Je ne peux pas croire que cela n'a pas plus de votes, tout à fait raison. –

1

Pourquoi croyez-vous qu'il existe des propriétés personnalisées dans l'en-tête? WriteStartDocument écrit l'en-tête avec ou sans l'attribut standalone

Votre code ajoute l'attribut que votre partenaire n'accepte pas.

Vous n'avez pas affiché le code utilisé pour produire le "utf-16", mais je suppose qu'il a écrit dans un StringWriter. Les chaînes dans .NET sont toujours UNICODE, et vous obtiendrez toujours utf-16 lorsque vous écrivez dans une chaîne. Si vous écrivez dans un flux, vous contrôlez l'encodage.

+0

Ah, OK je reçois ... si je retire la WriteStartDocument la version autonome ne va un moyen. Vous ne savez toujours pas comment supprimer les bits UTF. –

+0

utilisation WriteStartDocument(). Avez-vous encore UTF-16 avec le code que vous avez publié? –

+0

Oui, maintenant que j'ai enlevé le writer.WriteStartDocument (True) nous avons fait cela pour un en-tête:

2

Je sais que cela fait quelques mois que la question a été posée, mais je me sens obligé de mentionner un (de longue date ?) solution que j'ai trébuché à travers. Il supprime toute la déclaration xmldec, et tout ce dont vous avez besoin pour réécrire juste la déclaration dont vous avez besoin en écrivant une instruction de procession.

XmlFragmentWriter - Omiting the Xml Declaration and the XSD and XSI namespaces

Et voici la classe en VB

Imports System.Xml 
Imports System.IO 
Imports System.Text 

Class XmlFragmentWriter 
Inherits XmlTextWriter 

Public Sub New(ByVal w As TextWriter) 
    MyBase.New(w) 
End Sub 

Public Sub New(ByVal w As Stream, ByVal encoding As Encoding) 
    MyBase.New(w, encoding) 
End Sub 

Public Sub New(ByVal filename As String, ByVal encoding As Encoding) 
    MyBase.New(New FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None), encoding) 
End Sub 


Private _skip As Boolean = False 

Public Overrides Sub WriteStartAttribute(ByVal prefix As String, ByVal localName As String, ByVal ns As String) 
    ' STEP 1 - Omits XSD and XSI declarations. 
    ' From Kzu - http://weblogs.asp.net/cazzu/archive/2004/01/23/62141.aspx 
    If prefix = "xmlns" AndAlso (localName = "xsd" OrElse localName = "xsi") Then 
     _skip = True 
     Return 
    End If 
    MyBase.WriteStartAttribute(prefix, localName, ns) 

End Sub 

Public Overrides Sub WriteString(ByVal text As String) 
    If _skip Then 
     Return 
    End If 
    MyBase.WriteString(text) 

End Sub 

Public Overrides Sub WriteEndAttribute() 
    If _skip Then 
     ' Reset the flag, so we keep writing. 
     _skip = False 
     Return 
    End If 
    MyBase.WriteEndAttribute() 

End Sub 

Public Overrides Sub WriteStartDocument() 
    ' STEP 2: Do nothing so we omit the xml declaration. 
End Sub 
End Class 

et l'utilisation ici:

Dim f As New XmlSerializer(GetType(OFXg)) 
     Dim w As New XmlFragmentWriter("c:\books1.xml", Nothing) 
     w.Formatting = Formatting.Indented 
     w.WriteProcessingInstruction("xml", "version=""1.0""") 
     f.Serialize(w, RTofx) 
     w.Close() 

Bien sûr, la classe OFXg est un XMLSerializable

-1

Ce:

XmlWriterSettings xmlWriterSettings 
    = new XmlWriterSettings { OmitXmlDeclaration = true, }; 

vous donnera ceci:

<?xml version="1.0"?> 
+2

Err no. J'ai récemment utilisé omitxmldeclaration et supprime complètement cette ligne. –

0

Necromancing.

Vous pouvez créer votre propre XmlTextWriter et passer outre WriteStartDocument.

Exemple:

public class XmlTextWriterIndentedStandaloneNo : System.Xml.XmlTextWriter 
{ 

    public bool bStandAlone = false; 
    public bool bWriteStartDocument = true; 
    public bool bOmitEncodingAndStandAlone = true; 


    public XmlTextWriterIndentedStandaloneNo(System.IO.TextWriter w) 
     : base(w) 
    { 
     Formatting = System.Xml.Formatting.Indented; 
    } // End Constructor 


    public XmlTextWriterIndentedStandaloneNo(string strFileName, System.Text.Encoding teEncoding) 
     : base(strFileName, teEncoding) 
    { 
     Formatting = System.Xml.Formatting.Indented; 
    } // End Constructor 


    public XmlTextWriterIndentedStandaloneNo(System.IO.Stream w, System.Text.Encoding teEncoding) 
     : base(w, teEncoding) 
    { 
     Formatting = System.Xml.Formatting.Indented; 
    } // End Constructor 


    public override void WriteStartDocument(bool standalone) 
    { 
     if (bWriteStartDocument) 
     { 
      if (bOmitEncodingAndStandAlone) 
      { 
       this.WriteProcessingInstruction("xml", "version='1.0'"); 
       return; 
      } // End if (bOmitEncodingAndStandAlone) 

      base.WriteStartDocument(bStandAlone); 
     } 

    } // End Sub WriteStartDocument 


    public override void WriteStartDocument() 
    { 
     // Suppress by ommitting WriteStartDocument 
     if (bWriteStartDocument) 
     { 

      if (bOmitEncodingAndStandAlone) 
      { 
       this.WriteProcessingInstruction("xml", "version='1.0'"); 
       return; 
      } // End if (bOmitEncodingAndStandAlone) 

      base.WriteStartDocument(bStandAlone); 
      // False: Standalone="no" 
     } // End if (bWriteStartDocument) 

    } // End Sub WriteStartDocument 


} // End Class XmlTextWriterIndentedStandaloneNo 

VB.NET

Public Class XmlTextWriterIndentedStandaloneNo 
    Inherits System.Xml.XmlTextWriter 

    Public bStandAlone As Boolean = False 
    Public bWriteStartDocument As Boolean = True 
    Public bOmitEncodingAndStandAlone As Boolean = True 


    Public Sub New(w As System.IO.TextWriter) 
     MyBase.New(w) 
     Formatting = System.Xml.Formatting.Indented 
    End Sub 
    ' End Constructor 

    Public Sub New(strFileName As String, teEncoding As System.Text.Encoding) 
     MyBase.New(strFileName, teEncoding) 
     Formatting = System.Xml.Formatting.Indented 
    End Sub 
    ' End Constructor 

    Public Sub New(w As System.IO.Stream, teEncoding As System.Text.Encoding) 
     MyBase.New(w, teEncoding) 
     Formatting = System.Xml.Formatting.Indented 
    End Sub 
    ' End Constructor 

    Public Overrides Sub WriteStartDocument(standalone As Boolean) 
     If bOmitEncodingAndStandAlone Then 
      Me.WriteProcessingInstruction("xml", "version='1.0'") 
      Return 
     End If 
     ' End if (bOmitEncodingAndStandAlone) 
     If bWriteStartDocument Then 
      MyBase.WriteStartDocument(bStandAlone) 
     End If 
    End Sub 
    ' End Sub WriteStartDocument 

    Public Overrides Sub WriteStartDocument() 
     If bOmitEncodingAndStandAlone Then 
      Me.WriteProcessingInstruction("xml", "version='1.0'") 
      Return 
     End If 
     ' End if (bOmitEncodingAndStandAlone) 
     ' Suppress by ommitting WriteStartDocument 
     If bWriteStartDocument Then 
       ' False: Standalone="no" 
      MyBase.WriteStartDocument(bStandAlone) 
     End If 
     ' End if (bWriteStartDocument) 
    End Sub 
    ' End Sub WriteStartDocument 

End Class 
' End Class XmlTextWriterIndentedStandaloneNo 

Exemple d'utilisation:

//using (System.Xml.XmlTextWriter wr = new System.Xml.XmlTextWriter(System.IO.Path.Combine(strBasePath, "TestFile.xml"), System.Text.Encoding.UTF8)) 
//using (System.Xml.XmlWriter wr = System.Xml.XmlWriter.Create(System.IO.Path.Combine(strBasePath, "TestFile.xml"), xwsSettings)) 
using (System.Xml.XmlWriter wr = new XmlTextWriterIndentedStandaloneNo(System.IO.Path.Combine(strBasePath, "TestFile.xml"), System.Text.Encoding.UTF8)) 
{ 
    //wr.Formatting = System.Xml.Formatting.None; // here's the trick ! 

    xdoc.Save(wr); 
    wr.Flush(); 
    wr.Close(); 
} // End Using wr 
Questions connexes