2013-07-23 45 views
0

我有两个相同的XML文件,其中包含关于persons.they的信息只有它们的标签名称不同。例如,用于第一,我有反序列化xml到对象

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

和在第二个,我有

<name_person> 
<surname_person> 
<address_person> 

我需要“去串行化”它们变成在vb.net两个单独的对象。 我只有一个类的属性名称,姓氏,地址.. 是否有可能只使用这一类的第二个XML文件呢?因为后者的标签名称不匹配。

感谢

+0

如果使用File-> String-> XMLObject,则可以使用字符串函数修复标记。 – rheitzman

+0

在我的属性类中,是否可以确定正在读取的文件的类型,然后通知它有关要查找的标记名称。 例如如果Filename =“xml1”,那么 _ 其他 _ – user2092583

回答

0

您应该能够使用SerializationBinder在那里你可以指定(重映射)元素的类型反序列化。

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

+0

非常感谢你的解释非常明确 – user2092583

+0

我将创建另一个子类人,并覆盖活页夹,并仍然返回mybase .. – user2092583

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") 

结果将是元素名称将在两个文档中匹配,然后您可以运行您r解串器,而不必担心处理不匹配的元素名称。