【问题标题】:Serialize to XML and ignore objects with no value set序列化为 XML 并忽略未设置值的对象
【发布时间】:2013-07-15 04:54:08
【问题描述】:

我正在检索和反序列化 XML,更新单个对象值,然后(重新)序列化为 XML。

检索到的 XML 仅包括具有值的字段(即创建此 XML 的应用程序显然忽略了空值和零)。

但是,我的代码(如下)序列化了类中的所有对象,即使我没有设置值。

本质上,我只想返回我检索到的值并忽略其余的值。

我只想说,代码完全按照我的要求执行,而不是我希望它执行的操作(为简洁起见,以下内容经过编辑,但包含相关元素):

Private Sub Update_Name()

        'write 'name' to xml file

        Dim table As New table() ' 'table' is the name of my CLASS
        Dim serializer As New XmlSerializer(table.GetType())
        Dim ns As New XmlSerializerNamespaces()
        ns.Add("", "")
        Using reader = XmlReader.Create("C:/mwName_in.xml")
            table = CType(serializer.Deserialize(reader), table)
        End Using

        'update fields in xml table and save to file


        Dim name = table.name
        For Each nm In name
            nm.custom4 = "Subscriber" ' this is the only value that I am setting/updating

            Dim writer As XmlWriter

            Using writer = XmlWriter.Create("C:/mwName_out.xml")

                serializer.Serialize(writer, table, ns)
            End Using

            'THIS IS WHERE I POST THE RESULTING XML

        Next

End Sub

我的“传入”XML 如下所示:

<?xml version="1.0"?>
<table found="6" start="0" count="6" name="Name">
  <name>
    <code>AWEBSTER</code>
    <name>Alex Webster</name>
    <address1>West End Road</address1>
    <address2>Herne Bay</address2>
    <address3>Auckland</address3>
    <delivery1>West End Road</delivery1>
    <delivery2>Herne Bay</delivery2>
    <delivery3>Auckland</delivery3>
    <delivery4>Auckland</delivery4>
    <phone>021555 8888</phone>
    <category1>SHOP</category1>
    <category2>NZ</category2>
    <customertype>2</customertype>
    <debtorterms>-20</debtorterms>
    <creditorterms>-20</creditorterms>
    <recaccount>5500</recaccount>
    <payaccount>6500</payaccount>
    <suppliertype>2</suppliertype>
    <email>test@test.com</email>
    <productpricing>B</productpricing>
  </name>
</table>

我的传出 XML 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<table>
 <name>
  <hold>false</hold>
  <dateoflastsale>0001-01-01T00:00:00</dateoflastsale>
  <supplierpropmtpaymentterms>0</supplierpropmtpaymentterms>
  <custpromptpaymentterms>0</custpromptpaymentterms>
  <customertype>2</customertype>
  <suppliertype>2</suppliertype>
  <colour>0</colour>
  <d30plus>0</d30plus>
  <d60plus>0</d60plus>
  <d90plus>0</d90plus>
  <discount>0</discount>
  <ccurrent>0</ccurrent>
  <dcurrent>0</dcurrent>
  <creditorterms>-20</creditorterms>
  <debtorterms>-20</debtorterms>
  <paymentmethod>0</paymentmethod>
  <lastpaymentmethod>0</lastpaymentmethod>
  <splitpercent>0</splitpercent>
  <supppromptpaymentdiscount>0</supppromptpaymentdiscount>
  <receiptmethod>0</receiptmethod>
  <custpropmtpaymentdiscount>0</custpropmtpaymentdiscount>
  <dbalance>0</dbalance>
  <creditlimit>0</creditlimit>
  <kind>0</kind>
  <usernum>0</usernum>
  <lastmodifiedtime>0001-01-01T00:00:00</lastmodifiedtime>
  <abuid>0001-01-01T00:00:00</abuid>
  <delivery1>West End Road</delivery1>
  <delivery4>Auckland</delivery4>
  <delivery2>Herne Bay</delivery2>
  <delivery3>Auckland</delivery3>
  <email>test@test.com</email>
  <custom4>Subscriber</custom4>
  <address1>West End Road</address1>
  <address2>Herne Bay</address2>
  <address3>Auckland</address3>
  <name>Alex Webster</name>
  <phone>0215558888</phone>
  <productpricing>B</productpricing>
  <payaccount>6500</payaccount>
  <recaccount>5500</recaccount>
  <code>AWEBSTER</code>
  <category1>SHOP</category1>
  <category2>NZ</category2>
 </name>
</table>

显然,序列化已经获取了类“表”和“名称”中的所有对象,但我只想要设置了值的对象(即传入 XML 中的对象和我更新的一个值) - 'custom4',在这种情况下)。

问题是我不能使用 XmlIgnore(至少我认为我不能),因为我事先不知道哪些字段将被设置,哪些字段将为空/零 - 我只需要更新一个字段。

我没有包含整个类 - 它确实成功地序列化为传出的 XML(上图)。

提前非常感谢。这让我有点抓狂。

【问题讨论】:

    标签: vb.net xml-serialization


    【解决方案1】:

    为此,水合整个对象,然后将其重新序列化回 XML 似乎有点过头了。相反,您可以使用System.Xml.Linq 命名空间,如下所示(C# 中的代码,但很容易转移到 VB.NET)

    var doc = XDocument.Load("c:/oldfile.xml");
    var custom4 = doc.Root.Element("name").Element("custom4");
    custom4.Value = "whatever";
    doc.Save("c:/newfile.xml");
    

    【讨论】:

    • 感谢 CSJ。我同意你的观点,LINQ 可能是要走的路。这是一个更大项目的一部分,课程已经准备好了,我一直认为我在遵循最佳实践,直到陷入僵局。
    猜你喜欢
    • 1970-01-01
    • 2016-11-21
    • 2020-10-05
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多