我有两个相同的 XML 文件,其中包含有关人员的信息。它们仅在标签名称上有所不同。例如对于第一个,我有
<name>
<surname>
<address>...
在第二个中,我有
<name_person>
<surname_person>
<address_person>
我需要将它们“反序列化”为 vb.net 中的两个单独的对象。我只有一个具有属性名称、姓氏、地址的类。是否也可以将这一类用于第二个 XML 文件?因为后者的标签名称不匹配。
谢谢
我认为最简单的事情是分别控制反序列化。我寻找 XmlElement 属性的别名,但我没有看到类似的东西。此外,当您再次序列化对象时,它如何知道它应该使用哪些标签。
从第二个对象反序列化后,在代码中创建第一个类的新实例并复制属性就不会那么难了。
你也可以做这样的事情,这使得一个类非常擅长阅读,但你不应该使用这个类来写,否则它会写所有的属性。
VB.NET
<XmlRoot("PersonList")> _
Public Class PersonList
<XmlElement("person")> _
Public Property People() As Person()
Get
Return m_People
End Get
Set
m_People = Value
End Set
End Property
Private m_People As Person()
End Class
Public Class Person
Private _name As String
<XmlElement("name")> _
Public Property Name() As String
Get
Return _name
End Get
Set
_name = value
End Set
End Property
<XmlElement("name_person")> _
Public Property NamePerson() As String
Get
Return _name
End Get
Set
_name = value
End Set
End Property
End Class
C#
[XmlRoot("PersonList")]
public class PersonList {
[XmlElement("person")]
public Person[] People { get; set; }
}
public class Person {
private String _name;
[XmlElement("name")]
public String Name {get{return _name;} set{_name = value;}}
[XmlElement("name_person")]
public String NamePerson {get{return _name;} set{_name = value;}}
}
或者,看起来您可以使用原始类,但随后处理 XmlSerializer.UnknownElement 事件。
(未经测试)VB.Net
Private Shared Sub serializer_UnknownElement(sender As Object, e As XmlElementEventArgs)
Dim target = DirectCast(e.ObjectBeingDeserialized, Person)
If e.Element.Name = "name_person" Then
target.Name = e.Element.InnerText
End If
End Sub
C#
static void serializer_UnknownElement(object sender, XmlElementEventArgs e)
{
var target = (Person) e.ObjectBeingDeserialized;
if( e.Element.Name == "name_person")
{
target.Name = e.Element.InnerText;
}
}
但同样,这不会让您保存回旧格式,只能从旧格式加载到新类中。
参考:http ://weblogs.asp.net/psteele/archive/2011/01/31/xml-serialization-and-the-obsolete-attribute.aspx
参考:http: //msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.unknownelement.aspx
您应该能够使用SerializationBinder,您可以在其中指定(重新映射)被反序列化的元素的类型。
您可以使用 XSLT 更新第二个文档以匹配您期望的元素名称。这样,您就不必处理代码中的不同元素名称。
使用 XSLT 转换第二个文档,例如:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//name_person">
<name>
<xsl:apply-templates select="@*|node()" />
</name>
</xsl:template>
<xsl:template match="//surname_person">
<surname>
<xsl:apply-templates select="@*|node()" />
</surname>
</xsl:template>
<xsl:template match="//address_person">
<address>
<xsl:apply-templates select="@*|node()" />
</address>
</xsl:template>
</xsl:stylesheet>
它以编程方式将此应用于您的文档,在 C# 中,您可以执行以下操作:
XslCompiledTransformtransform = new XslCompiledTransform();
transorm.Load("update.xsl");
transorm.Transform("source.xml","new.xml");
在 VB 中:
Dim transform As XslTransform
transform = New XslTransform()
transform .Load("update.xsl")
transform .Transform("source.xml", "new.xml")
结果将是元素名称将在两个文档中匹配,然后您可以在 XML 上运行反序列化程序,而不必担心处理不匹配的元素名称。