2009-04-18 2 views
0

Ich habe eine E-Mail-Anwendung. Beim Senden an jeden Empfänger schreibe ich in eine XML-Datei namens mail.xml. Ich verwende den folgenden Code ein:Betroffen mit Schreiben von xml

Dim from As String = txtFrom.Text 
Dim txto As String = txtTo.Text 
Dim subj As String = txtSubject.Text 
Dim body As String = txtBody.Text 
Dim settings As New XmlWriterSettings() 
settings.Indent = True 
settings.NewLineOnAttributes = True 
Using writer As XmlWriter = XmlWriter.Create("C:\xmlmailfile.xml", settings) 
    writer.WriteStartDocument() 
    writer.WriteStartElement("EMail") 
    writer.WriteStartElement("From") 
    writer.WriteStartAttribute("From") 
    writer.WriteValue(from) 
    writer.WriteEndAttribute() 
    writer.WriteStartElement("To") 
    writer.WriteStartAttribute("To") 
    writer.WriteValue(txto) 
    writer.WriteEndAttribute() 
    writer.WriteStartElement("Subject") 
    writer.WriteStartAttribute("Subject") 
    writer.WriteValue(subj) 
    writer.WriteEndAttribute() 
    writer.WriteStartElement("Body") 
    writer.WriteStartAttribute("Body") 
    writer.WriteValue(body) 
    writer.WriteEndAttribute() 
    writer.WriteEndElement() 
    writer.WriteEndDocument() 
    writer.Flush() 
End Using 

Und der Ausgang ist:

<?xml version="1.0" encoding="utf-8" ?> 
<EMail> 
    <From From="[email protected]"> 
    <To To="[email protected]"> 
    <Subject Subject="Hi"> 
     <Body Body="Hello" /> 
    </Subject> 
    </To> 
    </From> 
</EMail> 

Hier bin ich nicht in der Lage vorhandene Ausgabe anhängen. Nur ein "E-Mail" -Abschnitt wird ausgegeben. Ich möchte einen Abschnitt "E-Mail" für jeden Empfänger hinzufügen. Im obigen Code ersetzen jedoch neue Abschnitte zuvor geschriebene.

Wie kann ich das erreichen?

+0

Ihr XML-Design ist komplett fehlerhaft! – Cerebrus

Antwort

7

Ein XML-Dokument kann nur ein einzelnes Wurzelelement haben. Ich schlage vor, Sie haben eine Wurzel Emails Element mit Email Elemente darunter. Beachten Sie, dass Sie immer noch keine neuen Elemente in derselben Datei anhängen können - Sie müssten die vorhandene Datei lesen und neu schreiben. In der Theorie könnte überschreiben Sie einfach die letzte Zeile (Sie wissen immer, wie lange es sein wird, so können Sie nur an der richtigen Stelle suchen), aber es ist robuster, die Datei in den Speicher zu lesen, ein neues Email Element anhängen, und dann schreibe das ganze Dokument erneut aus.

Ich denke auch, es ist ein wenig seltsam, das Body Element innerhalb das Thema Element zu haben. Ich würde eine Struktur wie folgt vorschlagen:

<?xml version="1.0" encoding="utf-8" ?> 
<Emails> 
    <Email> 
    <From Address="[email protected]"> 
    <Recipient Type="To" Address="[email protected]" /> 
    <Recipient Type="Cc" Address="[email protected]" /> 
    <Subject>Hi</Subject> 
    <Body>Body text</Body> 
    </Email> 
    <Email> 
    <!-- Second email comes here --> 
    </Email> 
</Emails> 
+0

Große Antwort! (wie üblich) – Cerebrus

+0

Kannst du ein Beispiel zeigen, wie man die Datei in den Speicher liest, ein neues E-Mail-Element anfügt und meinen Code ändert, um das obige Ergebnis zu erhalten – user42348

+0

@ ramyatk06: Ich habe gerade jetzt keine Zeit, das zu tun nicht in VB, aber ich bin sicher, dass Sie viele Beispiele online finden können. Ich schlage vor, dass Sie entweder LINQ to XML verwenden (wenn Sie .NET 3 verwenden).5) oder die DOM API (XmlDocument, XmlElement etc). XmlWriter ist effizient, aber schwerer zu korrigieren. –

0

Neben Jon Vorschlag über die notwendigen Änderungen an Ihren XML-Implementierung, werden Sie auch über die XmlWriter der WriteXXX Methoden zur Schleife benötigen. Beginnen Sie mit dem E-Mail-Element und der Schleife für jeden Empfänger.

0

Als Antwort auf Ihre Kommentare über sie im Speicher ändern:

Betrachten wir ein Schema wie folgt zu schreiben:

auf sie
<?xml version="1.0" encoding="utf-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:complexType name="FromType"> 
    <xs:attribute name="Address" type="xs:string"/> 
    </xs:complexType> 
    <xs:simpleType name="RecipientMethod"> 
    <xs:restriction base="xs:string"> 
     <xs:enumeration value="To"/> 
     <xs:enumeration value="Cc"/> 
     <xs:enumeration value="Bcc"/> 
    </xs:restriction> 
    </xs:simpleType> 
    <xs:complexType name="RecipientType"> 
    <xs:attribute name="Type" type="RecipientMethod"/> 
    <xs:attribute name="Address" type="xs:string"/> 
    </xs:complexType> 
    <xs:complexType name="Email"> 
    <xs:sequence> 
     <xs:element name="From" type="FromType" minOccurs="1" maxOccurs="1"/> 
     <xs:element name="Recipient" type="RecipientType" minOccurs="1" maxOccurs="unbounded"/> 
     <xs:element name="Subject" type="xs:string" minOccurs="0" maxOccurs="1"/> 
     <xs:element name="Body" type="xs:string" minOccurs="0" maxOccurs="1"/> 
    </xs:sequence> 
    </xs:complexType> 
    <xs:complexType name="Emails"> 
    <xs:sequence> 
     <xs:element name="Emails" type="Email" minOccurs="1" maxOccurs="unbounded"/> 
    </xs:sequence> 
    </xs:complexType> 
    <xs:element name="Emails" type="Emails"/> 
</xs:schema> 

und führen Sie das Schema Compiler xsd.exe (here)

Mit der Klasse, die es erzeugt, stellen Sie einfach die Mitglieder so ein:

Sobald die Mitglieder gesetzt sind, dies zu tun:

FileStream f ... 
XmlSerializer x = new XmlSerializer(e, f); 
x.Serialize(e); 

Ebenso können Sie deserialisieren:

Emails ne = x.DeSerialize(); 

Ändern Sie dann eine neue E-Mail hinzuzufügen:

Email newEmail = Email[ne.Email.Length + 1]; 
for(int i = 0; i < ne.Email.Length; i++) 
    newEmail[i] = ne.Email[i]; 
newEmail[ne.Email.Length] = new Email(); 
.... 
ne.Email = newEmail; 

dann serialisiert es zurück.

+0

Entschuldigung, ich habe C# -Syntax verwendet - Sie können stattdessen xsd.exe ausführen, um VB-Code zu generieren – paquetp