0

我有两个相同的 XML 文件,其中包含有关人员的信息。它们仅在标签名称上有所不同。例如对于第一个,我有

<name>
<surname>
<address>... 

在第二个中,我有

<name_person>
<surname_person>
<address_person>

我需要将它们“反序列化”为 vb.net 中的两个单独的对象。我只有一个具有属性名称、姓氏、地址的类。是否也可以将这一类用于第二个 XML 文件?因为后者的标签名称不匹配。

谢谢

4

3 回答 3

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反序列化:不同的xml架构映射到同一个C#类

或者,看起来您可以使用原始类,但随后处理 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

于 2013-07-23T18:17:24.273 回答
0

您应该能够使用SerializationBinder,您可以在其中指定(重新映射)被反序列化的元素的类型。

于 2013-07-23T18:16:36.397 回答
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 上运行反序列化程序,而不必担心处理不匹配的元素名称。

于 2013-07-23T19:36:50.183 回答