2013-07-23 89 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解串器,而不必擔心處理不匹配的元素名稱。