14

私は制御できない次の XML 構造 (簡潔にするために編集) を持っています。

<GetVehicles>
    <ApplicationArea>
        <Sender>
            <Blah></Blah>
        </Sender>
    </ApplicationArea>
    <DataArea>
        <Error>
            <Blah></Blah>
        </Error>
        <Vehicles>
            <Vehicle>
                <Colour>Blue</Colour>
                <NumOfDoors>3</NumOfDoors>
                <BodyStyle>Hatchback</BodyStyle>
            <Vehicle>
        </Vehicles>
    </DataArea>
</GetVehicles>

私は次のクラスを持っています:

[XmlRoot("GetVehicles"), XmlType("Vehicle")]
public class Vehicle
{
    public string Colour { get; set; }
    public string NumOfDoors { get; set; }
    public string BodyStyle { get; set; }
}

XML をこの Vehicle クラスの 1 つのインスタンスに逆シリアル化できるようにしたいと考えています。99% の場合、XML は 1 つの「Vehicle」要素のみを返す必要があります。「Vehicles」要素内に複数の「Vehicle」要素が含まれている場合、まだ対処していません。

残念ながら、XML データは現在クラスのプロパティにマップされていません。Deserialize メソッドを呼び出すと、空白のままになります。

完全を期すために、ここに私の Deserialize メソッドを示します。

private static T Deserialize<T>(string data) where T : class, new()
{
    if (string.IsNullOrEmpty(data))
        return null;

    var ser = new XmlSerializer(typeof(T));

    using (var sr = new StringReader(data))
    {
        return (T)ser.Deserialize(sr);
    }
}

「ApplicationArea」、「Error」などの他の親要素は気にしません。「Vehicle」要素内のデータを抽出することにのみ関心があります。XML からこのデータのみを逆シリアル化するにはどうすればよいですか?

4

2 に答える 2

11

イリヤの答えに基づいて構築:

すでにノードがロードされているため、これはわずかに最適化できます。xml を文字列に渡す必要はなく ( を使用vehicle.ToString())、シリアライザーが再解析する必要があるだけです ( を使用StringReader)。

代わりに、次を使用してリーダーを直接作成できますXNode.CreateReader

private static T Deserialize<T>(XNode data) where T : class, new()
{
    if (data == null)
        return null;

    var ser = new XmlSerializer(typeof(T));
    return (T)ser.Deserialize(data.CreateReader());
}

または、データが の場合は、次XmlNodeを使用しXmlNodeReaderます。

private static T Deserialize<T>(XmlNode data) where T : class, new()
{
    if (data == null)
        return null;

    var ser = new XmlSerializer(typeof(T));
    using (var xmlNodeReader = new XmlNodeReader(data))
    {
        return (T)ser.Deserialize(xmlNodeReader);
    }
}

次に、次を使用できます。

var vehicle = XDocument.Parse(xml)
                       .Descendants("Vehicle")
                       .First();

Vehicle v = Deserialize<Vehicle>(vehicle);
于 2014-11-26T15:42:53.310 に答える