0

内部のxml要素を同等のクラスに逆シリアル化することは可能ですか?私は次のxmlフラグメントを持っています:

<?xml version="1.0" encoding="utf-8" ?>
<tileconfiguration xmlns="http://somenamespace/tile-configuration">
   <tile top_left_x="3" top_left_y="1" bottom_right_x="38" bottom_right_y="48">
     <child>
     </child>
   </tile>
</tileconfiguration>

要素を表す同等のクラス<tile />

[System.Xml.Serialization.XmlRoot(ElementName = "tile")]
public class Tile : System.Xml.Serialization.IXmlSerializable
{
    public System.Xml.Schema.XmlSchema GetSchema()
    {
        throw new NotImplementedException();
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        throw new NotImplementedException();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        throw new NotImplementedException();
    }
}

<tile />問題は、-内のインスタンスを逆シリアル化しようとするたびに、XMLデシリアライザーがドキュメント(2,2)でエラーを<tile_configuration />スローすることです。

        System.Xml.Serialization.XmlSerializer serial = new System.Xml.Serialization.XmlSerializer(typeof(Tile));
        System.IO.TextReader t = new System.IO.StreamReader("c:\\temp\\deserial.xml");
        Tile q = (Tile)serial.Deserialize(t);

それを直接表現して逆シリアル化するクラスを作成する<tile_configuration />と、それは正常に機能し、デバッガーはクラスのReadXmlメソッドに入り、TileConfigurationそこから子(および子孫)要素の解析を管理でき<tile />ます-ただし、これには、の再読み取りが必要です。毎回xmlファイル全体。

一言で言えば; XMLファイル全体を読み書きする必要がありますか?シリアル化/逆シリアル化を使用するたびにルートxml要素から開始しますか、それとも無関係な外部要素を無視して、関連する子xml要素を直接逆シリアル化する方法がありますか?パーサーチャッキングエラーのない同等のコード?

とても感謝しております。

4

3 に答える 3

0

はい。1つのアイデアは、xmlをロードし、Xpathクエリを使用して目的のノードを選択することです。次に、クエリの結果で表されるxmlを逆シリアル化します。

于 2012-08-03T17:04:27.563 に答える
0

外側の要素を無視して、完全な制御とオーバーヘッドの少ない高速な実装を行いたい場合は、を使用するのではなく、それぞれXMLSerializerを使用することをお勧めします。XmlReaderXmlWriter

XmlReaderを使用して中間DOMを構築し、を使用しXMLSerializerてDOMを出力ファイルに書き込むことにより、組み合わせたアプローチを作成することもできます。

于 2012-08-03T17:25:09.950 に答える
0

XMLについて示したことを考えると、IXmlSerializableを実装する必要はないはずです。あなたはこれを試すことができます:

[XmlRoot("tileconfiguration")]
public class TileConfiguration
{
    [XmlElement("tile")]
    public List<Tile> Tiles { get; set; }
}

[XmlRoot("tile")]
public class Tile
{
    [XmlAttribute("top_left_x")]
    public int TopLeftX { get; set; }

    [XmlAttribute("top_left_y")]
    public int TopLeftY { get; set; }

    [XmlAttribute("bottom_right_x")]
    public int BottomRightX { get; set; }

    [XmlAttribute("bottom_right_y")]
    public int BottomRightY { get; set; }

    [XmlElement("child")]
    public List<Child> children { get; set; }
}

[XmlRoot("child")]
public class Child
{
}

XmlSerializer serializer = XmlSerializer(typeof(TileConfiguration));
TileConfiguration tileConfiguration = (TileConfiguration)serializer.Deserialize(stream);

XmlReaderを使用して、必要な要素をフェッチすることもできます。

List<Tile> tiles = new List<Tile>();
XmlSerializer serializer = XmlSerializer(typeof(Tile));

using (XmlTextReader xr = new XmlTextReader(xmlStream))
{
    while (!xr.EOF)
    {
        xr.MoveToContent();
        xr.ReadToDescendant("tile");

        if (xr.Name == "tile")
        {
            string tileXml = xr.ReadOuterXml();
            using (StringReader tileReader = new StringReader(tileXml))
            {
                Tile tile = (Tile)serializer.Deserialize(tileReader);
                tiles.Add(Tile);
            }
        }
        else
        {
            xr.ReadEndElement();
        }
    }
}
于 2012-08-03T20:49:09.027 に答える