0

個人に関する情報を含む 2 つの同一の XML ファイルがあります。それらはタグ名のみが異なります。たとえば、最初に、私は持っています

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

そして2番目のものでは、私は持っています

<name_person>
<surname_person>
<address_person>

vb.netでそれらを2つの別々のオブジェクトに「逆シリアル化」する必要があります。プロパティ Name,Surname,Address を持つクラスが 1 つしかありません。この 1 つのクラスだけを 2 番目の XML ファイルにも使用できますか?後者のタグ名が一致しないためです。

ありがとう

4

3 に答える 3

1

最も簡単なことは、逆シリアル化を個別に制御することだと思います。XmlElement 属性のエイリアスを探しましたが、そのようなものは見つかりませんでした。さらに、オブジェクトを再度シリアライズするとき、使用するタグをどのように知るのでしょうか。

2 番目のオブジェクトから逆シリアル化すると、最初のクラスの新しいインスタンスを作成し、プロパティをコピーすることはコードで難しくありません。

このようなことを行うこともできます。これにより、読み取りに優れたクラスが作成されますが、このクラスを書き込みに使用しないでください。そうしないと、すべてのプロパティが書き込まれます。

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

XSLT を使用して 2 番目のドキュメントを更新し、期待する要素名に一致させることができます。そうすれば、コード内のさまざまな要素名を処理する必要がなくなります。

次のような XSLT を使用して 2 番目のドキュメントを変換します。

<?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 に答える
0

逆シリアル化される要素のタイプを指定 (再マップ) できるSerializationBinderを使用できるはずです。

于 2013-07-23T18:16:36.397 に答える