将XML属性添加到从.NET序列化的对象中

huangapple go评论63阅读模式
英文:

adding Xml attributes to objects serialized from .NET

问题

以下是您要翻译的内容:

I have a class called CustomerDetails, and I manage these objects in a System.Collections.Generic.List(Of CustomerDetails). I serialize this object in an ordinary way...

Private Sub CustomerDetailsExportToXml(Details As System.Collections.Generic.List(Of CustomerDetails))
Dim x As New System.Xml.Serialization.XmlSerializer(Details.GetType)
Using s As New FileStream("customerdetails.xml", FileMode.Create)
x.Serialize(s, Details)
End Using
End Sub

...and get ordinary Xml...




MSD
Main Street Diner

To aid readability, I want to add an attribute to the CustomerDetails tag called "Acronym" that would contain the value of the tag:

I can do this in a post-serialization method where I load/modify/save the Xml, but I'm afraid of the resulting Xml not being de-serializable. Can the addition of the attribute be done at time of serialization?

英文:

I have a class called CustomerDetails, and I manage these objects in a System.Collections.Generic.List(Of CustomerDetails). I serialize this object in an ordinary way...

    Private Sub CustomerDetailsExportToXml(Details As System.Collections.Generic.List(Of CustomerDetails))
        Dim x As New System.Xml.Serialization.XmlSerializer(Details.GetType)
        Using s As New FileStream("customerdetails.xml", FileMode.Create)
        x.Serialize(s, Details)
        End Using
    End Sub

...and get ordinary Xml...

  <?xml version="1.0"?>
  <ArrayOfCustomerDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <CustomerDetails>
      <Acronym>MSD</Acronym>
      <FriendlyName>Main Street Diner</FriendlyName>
    </CustomerDetails>
  </ArrayOfCustomerDetails>

To aid readability, I want to add an attribute to the CustomerDetails tag called "Acronym" that would contain the value of the <Acronym> tag:

&lt;CustomerDetails Acronym=&quot;MSD&quot;&gt;

I can do this in a post-serialization method where I load/modify/save the Xml, but I'm afraid of the resulting Xml not being de-serializable. Can the addition of the attribute be done at time of serialization?

答案1

得分: 2

以下是翻译好的内容:

自从您似乎已经有与element相同值的Acronym,这应该很容易让序列化程序为您完成。很可能现在您有类似这样的内容:

public class CustomerDetails
{
    public string Acronym {get;set;}
}

要将其变成一个属性,您只需要这样做:

public class CustomerDetails
{
    [XmlAttribute]
    public string Acronym {get;set;}
}

您也可以在没有属性的情况下通过手动配置序列化程序来实现,但这需要更多的工作

英文:

Since you already seem to have Acronym with the same value as an element, this should be pretty simple to get the serializer to do for you. Presumably right now you have something like:

public class CustomerDetails
{
    public string Acronym {get;set;}
}

To make that an attribute instead, all you have to do is ask:

public class CustomerDetails
{
    [XmlAttribute]
    public string Acronym {get;set;}
}

You can also do this without attributes by configuring the serializer manually, but it is a lot more work.

答案2

得分: 1

更新

Marc Gravell的回答更为简洁,并保持易于反序列化。

这里有一个使用XmlAttribute装饰器的示例:https://dotnetfiddle.net/6T0U4d

原始回答

> 我可以在后序列化的方法中做到这一点,在那里我加载/修改/保存Xml,但我担心生成的Xml可能无法反序列化。可以在序列化时添加属性吗?

是的,你是正确的。如果你干扰序列化输出,那么它可能无法被反序列化。

然而,你所询问的可以通过以下步骤轻松实现:

  1. 不使用FileStream,而是使用StringWriter将输出作为内存字符串获取
  2. 将XML文本加载到XDocument
  3. 循环遍历ArrayOfCustomerDetails元素中的CustomerDetails元素
  4. 将属性值设置为Acronym元素的值
  5. 移除Acronym元素
  6. 将XDocument XML保存到文件中

例如:

Dim serializer = New XmlSerializer(details.GetType())
Dim xmlLiteral = String.Empty
Using writer = New StringWriter()
	serializer.Serialize(writer, details)
	xmlLiteral = writer.ToString()
End Using

Dim detailsXmlDocument = XDocument.Parse(xmlLiteral)
For Each customerDetailsElement In detailsXmlDocument.Element("ArrayOfCustomerDetails").Elements("CustomerDetails")
	customerDetailsElement.SetAttributeValue("Acronym", customerDetailsElement.Element("Acronym").Value)
	customerDetailsElement.Element("Acronym").Remove()
Next

IO.File.WriteAllText("customerdetails.xml", detailsXmlDocument.ToString())

Fiddle: https://dotnetfiddle.net/kAz5Ol

你可以通过简单地反转这个过程使反序列化工作。

英文:

Update

Marc Gravell's answer is much more concise and keeps it so it can be deserialized easily too.

Here is a fiddle using the XmlAttribute decorator: https://dotnetfiddle.net/6T0U4d

Original Answer

> I can do this in a post-serialization method where I load/modify/save the Xml, but I'm afraid of the resulting Xml not being de-serializable. Can the addition of the attribute be done at time of serialization?

That is correct. If you mess with the serialization output then it is unlikely that it will be deserializable.

However, what you're asking can be done pretty easily by following these steps:

  1. Instead of using a FileStream you can use a StringWriter to get the output as an in-memory string
  2. Take the XML literal and load it into an XDocument
  3. Loop over the CustomerDetails elements in the ArrayOfCustomerDetails element
  4. Set the attribute value to the Acronym element value
  5. Remove the Acronym element
  6. Save the XDocument XML to your file

For example:

Dim serializer = New XmlSerializer(details.GetType())
Dim xmlLiteral = String.Empty
Using writer = New StringWriter()
	serializer.Serialize(writer, details)
	xmlLiteral = writer.ToString()
End Using

Dim detailsXmlDocument = XDocument.Parse(xmlLiteral)
For Each customerDetailsElement In detailsXmlDocument.Element(&quot;ArrayOfCustomerDetails&quot;).Elements(&quot;CustomerDetails&quot;)
	customerDetailsElement.SetAttributeValue(&quot;Acronym&quot;, customerDetailsElement.Element(&quot;Acronym&quot;).Value)
	customerDetailsElement.Element(&quot;Acronym&quot;).Remove()
Next

IO.File.WriteAllText(&quot;customerdetails.xml&quot;, detailsXmlDocument.ToString())

Fiddle: https://dotnetfiddle.net/kAz5Ol

You could get the deserialization to work by just reversing the process.

huangapple
  • 本文由 发表于 2023年3月3日 22:26:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628308.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定