我有两个相同的XML文件,其中包含有关人员的信息。他们的标签名称不同。例如对于第一个,我有
<name>
<surname>
<address>...
在第二个,我有
<name_person>
<surname_person>
<address_person>
我需要在vb.net中将它们“反序列化”为两个单独的对象。 我只有一个类具有属性名称,姓氏,地址.. 是否可以仅将这一个类用于第二个XML文件?因为后者的标记名称不匹配。
感谢
答案 0 :(得分:1)
最简单的事情,我认为是分别控制反序列化。我找了寻找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;}}
}
参考:XML deserialize: different xml schema maps to the same C# class
或者,看起来您可以使用原始类,但随后处理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
答案 1 :(得分:0)
您应该可以使用SerializationBinder来指定(重新映射)要反序列化的元素的类型。
答案 2 :(得分:0)
您可以使用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上运行反序列化器,而不必担心处理不匹配的元素名称。