2009-04-18 2 views
0

私はメールアプリケーションを持っています。各受信者に送信する際に、mail.xmlという名前のXMLファイルに書き込んでいます。私は、次のコードを使用します。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 

を、出力は次のとおりです。

ここ
<?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> 

私は既存の出力に追加することはできませんよ。 「電子メール」セクションは1つだけ出力されます。私は各受信者のための "電子メール"セクションを追加したいと思います。しかし、上記のコードでは、新しいセクションは以前に書かれたものを置き換えます。

どうすればこの問題を解決できますか?

+0

あなたのXMLデザインには完全な欠陥があります! – Cerebrus

答えて

7

XMLドキュメントには、単一のルート要素しか含めることができません。私はあなたの下にEmail要素を持つルートEmails要素があることをお勧めします。同じファイル内に新しい要素を追加することはできないことに注意してください。既存のファイルを読み込んで書き直す必要があります。理論的には、のように最後の行を上書きするだけです(ファイルの長さを知っているので、正しい場所を探すことができます)。ファイルをメモリに読み込み、新しいEmail要素を追加してからドキュメント全体をもう一度書き出します。

Body要素の中にという要素があるのはちょっと奇妙だと思います。あなたのXMLに必要な変更についてJonの提案を実装することに加え

<?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

すばらしい答え! (通常通り) – Cerebrus

+0

ファイルをメモリに読み込んで新しい電子メール要素を追加する方法と、上の結果を得るためにコードを変更する方法を示すことができます – user42348

+0

@ ramyatk06:私は今、特にそうする時間がありませんVBではなく、たくさんの例をオンラインで見つけることができると確信しています。私はLINQ to XML(.NET 3を使用している場合)を使用することをお勧めします。5)またはDOM API(XmlDocument、XmlElementなど)を使用します。 XmlWriterは効率的ですが、正しく取得するのは難しいです。 –

0

は、あなたもしたXmlWriterのWriteXXXメソッドをループにする必要があります:私はこのような構造をお勧めしたいです。 Email要素から開始し、受信者ごとにループします。メモリにそれを修正することについてコメントへの応答として

0

here

<?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> 

し、その上に、スキーマコンパイラXsd.exeではを実行します。

は次のようにスキーマを書いて考えてみましょう

生成するクラスでは、次のようにメンバーを設定するだけです。

Emails e= new Emails(); 
e.Email = new Email[2]; 
e.Email[0] = new Email(); 
e.Email[0].From = new FromType(); 
... 

メンバーを設定したら、これを実行します。

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

を、あなたがデシリアライズすることができます

Emails ne = x.DeSerialize(); 

次に、新しいメールを追加するためにそれを変更します。シリアライズその後、

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; 

をそれは戻ってくる。

+0

申し訳ありませんが、私はC#構文を使用しました。代わりにxsd.exeを実行してVBコードを生成することができます – paquetp

関連する問題