关注编写xml

时间:2009-04-18 09:00:14

标签: xml vb.net

我有邮件申请。在发送给每个收件人时,我正在写一个名为mail.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="abc@xyz.com">
  <To To="def@pqr.com">
    <Subject Subject="Hi">
      <Body Body="Hello" /> 
    </Subject>
  </To>
  </From>
 </EMail>

这里我无法附加到现有输出。只输出一个“电子邮件”部分。我想为每个收件人添加“电子邮件”部分。但是,在上面的代码中,新的部分替换了之前编写的部分。

我该如何做到这一点?

3 个答案:

答案 0 :(得分:7)

XML文档只能有一个根元素。我建议你有一个根Emails元素,其下面有Email个元素。请注意,您仍然无法在同一文件中追加新元素 - 您必须阅读现有文件并重写它。理论上你可以只是覆盖最后一行(你总是知道它会有多长,所以你可以找到正确的位置)但是将文件读入内存更加健壮,附加一个新的Email元素,然后再次写出整个文档。

我还认为在主题元素中使用Body元素有点奇怪。我建议这样的结构:

<?xml version="1.0" encoding="utf-8" ?> 
<Emails>
  <Email>
    <From Address="abc@xyz.com">
    <Recipient Type="To" Address="def@pqr.com" />
    <Recipient Type="Cc" Address="ghi@pqr.com" />
    <Subject>Hi</Subject>
    <Body>Body text</Body> 
  </Email>
  <Email>
    <!-- Second email comes here -->
  </Email>
</Emails>

答案 1 :(得分:0)

除了实现Jon关于对XML进行必要修改的建议之外,您还需要循环遍历XmlWriter的WriteXXX方法。从每个收件人的Email元素和循环开始。

答案 2 :(得分:0)

作为对你在内存中修改它的评论的回应:

考虑编写这样的模式:

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

使用它生成的类,您只需设置成员,如下所示:

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;

然后将其序列化。