1

クラス CarResource、クラス RaceCarResource : public CarResource、およびクラス SuperDuperUltraRaceCarResource : public RaceCarResource があるとします。

単一のメソッド LoadFromXML を使用してデータをロードできるようにしたいと考えています。

CarResource:LoadFromXML を取得してそのデータをロードし、RaceCarResource を呼び出して CarResource:LoadFromXML を呼び出してから独自の追加データなどをロードするにはどうすればよいでしょうか?

XmlTextReader を使用すると、ファイル全体を一度に解析する方法しかわかりません。その使用方法はわからないため、最初に CarResource:LoadFromXML でその処理を実行し、次に RaceCarResource などを実行できます。

私が言いたいことが少しでも明確になることを願っています:)

4

5 に答える 5

1
public class CarResource
{
    public virtual void LoadFromXML(String xmlData)
    {
        ...
    }
}

public class RaceCarResource : CarResource
{
    public override void LoadFromXML(String xmlData)
    {
        base.LoadFromXML(xmlData);
        ...
    }
}

...等々。new キーワードは、継承されたメソッドを非表示にしますが、子クラスから呼び出すことができるようにします。

XML の実際の解析に関しては、いくつかのオプションがあります。私の最初の提案は、XML ファイル全体をメモリに読み込んでから、LINQ to XML を使用してクラスを解析し、データを設定することです。XmlSerializer を試すこともできます (LINQ to XML の実装は簡単ですが、コード ベースのサイズが大きくなるにつれて、Xml シリアル化によってメンテナンスが容易になります)。

于 2010-01-06T16:17:48.943 に答える
0

XMLの逆シリアル化を使用するために、インスタンスメソッドは現在のオブジェクトを事実上「不変」にしますが、次のようなものを提案します。

public class CarResource
{
    public CarResource LoadNewFromXML(string xml)
    {
        XmlSerializer ser = new XmlSerializer(this.GetType());
        object o = null;
        using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(xml)))
        {
            o = ser.Deserialize(ms);
        }
        return o as CarResource;
    }
}

public class RaceCarResource : CarResource
{
}

public class SuperRaceCarResource : RaceCarResource
{ 
}

呼び出しコードは次のようになります。

RaceCarResource car = new RaceCarResource();
car = car.LoadNewFromXML("<RaceCarResource/>") as RaceCarResource;

SuperRaceCarResource sc = new SuperRaceCarResource();
sc = sc.LoadNewFromXML("<SuperRaceCarResource/>") as SuperRaceCarResource;
于 2010-01-06T16:52:17.470 に答える
0

XML が .net XML シリアル化と互換性がない場合、最も簡単な方法は、XML が表すリソースのタイプを検出するファクトリを作成し、それを適切に処理することです。解析をオブジェクトに入れたい場合は、仮想メソッドを使用して、オブジェクトの作成後に内部を解析します。

class CarResource
{
    public string Color { get; private set; }

    internal virtual void ReadFrom(XmlReader xml)
    {
        this.Color = xml.GetAttribute("colour");
    }
}

class RaceCarResource : CarResource
{
    public string Sponsor { get; private set; }

    internal override void ReadFrom(XmlReader xml)
    {
        base.ReadFrom(xml);
        this.Sponsor = xml.GetAttribute("name-on-adverts");
    }
}

class SuperDuperUltraRaceCarResource : RaceCarResource
{
    public string Super { get; private set; }

    internal override void ReadFrom(XmlReader xml)
    {
        base.ReadFrom(xml);
        this.Super = xml.GetAttribute("soup");
    }
}

class CarResourceFactory
{
    public CarResource Read(XmlReader xml)
    {
        CarResource car;

        switch (xml.LocalName)
        {
            case "ordinary-car": car = new CarResource(); break;
            case "racecar": car = new RaceCarResource(); break;
            case "super_duper": car = new SuperDuperUltraRaceCarResource(); break;
            default: throw new XmlException();
        }

        XmlReader sub = xml.ReadSubtree();

        car.ReadFrom(sub);

        sub.Close();

        return car;
    }
}

サブタイプの XML で、スーパータイプのコンテンツの前後に子要素が厳密に追加されている場合、これは問題なく機能します。それ以外の場合は、スーパータイプのシリアル化を再利用して、より小さなメソッドに分割するために、より多くの作業を行う必要があります (たとえば、ベースには、車輪の数、ドア、エンジンのサイズをロードするメソッドがあります。レースカーはLoadDoorData、レースカーには、ドアとホイールのデータの間にエアロフォイルのデータがあります. 論理的な順序付けが課されていない形式 (XMI, RDF) の場合、ローカル名を調べて、呼び出す特殊なメソッドを決定する必要があります.仮想メソッドと組み合わせる. その場合は、別のシリアル化ヘルパーを使用することをお勧めします.LoadAeroFoilDataLoadWheelData

作成するタイプのセットがいくつかのタイプに固定されていない場合は、ファクトリで他のメカニズムを使用できます。

于 2010-01-06T18:08:39.237 に答える
0

ロード元の XML ファイルの構造に応じて、XML シリアライゼーションを使用することもできます。load メソッドをオーバーライドして (その後、後続のクラスでオーバーライドして)、特定の情報をロードしたり、単に属性を使用したりすることができます。参照: http://msdn.microsoft.com/en-us/library/ms950721.aspx

于 2010-01-06T16:20:29.127 に答える
0

いくつかのオプションがあります。

Linq to XML を使用して子エンティティをクエリし、それらのノードを他のクラスに渡すことができます。これはおそらく最も効率的な方法です。

xmlnavigator を使用できますが、ここでも適切な子ノードのみを渡します...参照: C# で独自の XPathNavigator を実装する

単純に xml シリアライゼーション (XmlSerialize XmlDeserialize) を使用できます。「C# - オブジェクト自体を xml デシリアライズする方法」を参照してください。

于 2010-01-06T16:21:35.693 に答える