7

次のXMLの例を考えると、Type1とType2の間のバインドされていない数の選択肢のシーケンスを含むものとしてRootを定義するスキーマを想像できます。

<Root>
    <Type1 />
    <Type2 />
    <Type2 />
    <Type1 />
</Root>

私はXSD.exeツールからの移行をテストしています。このツールは、型安全性を追加しますが、多くの厄介な問題があります。この場合のXSDツールは、Root内にSystem.Objectタイプの配列を作成するだけであり、そこにあるオブジェクトのタイプ(Type1またはType2)を把握する必要があります。完全にエレガントというわけではありませんが、少なくとも秩序を維持します。

問題は、LINQ to XSDがオブジェクトを作成するときに、ルートをType1とType2の2つの独立したリストを持つものとして定義することです。これはタイプセーフであるという点で優れていますが、要素の順序が失われているように見えます。codeplexのソースからLINQtoXSDをビルドしました。

LINQ to XSDを使用して、これらの要素の順序を保持するにはどうすればよいですか?

4

2 に答える 2

2

Choiceのラッパーを作成するのはどうですか?アクセスするタイプを次のように制限します。

class Choice
{
    private object _value;

    public ChoiceEnum CurrentType { get; private set; }

    public Type1 Type1Value
    {
        get { return (Type1) _value; }
        set { _value = value; CurrentType = ChoiceEnum.Type1; }
    }

    public Type2 Type2Value
    {
        get { return (Type2) _value; }
        set { _value = value; CurrentType = ChoiceEnum.Type2; }
    }
}

これは簡略化されたバージョンであり、さらに検証を追加する必要があります(_value正しいタイプの場合、現在のタイプは何ですか_valueなど)。

次に、LINQでフィルタリングできます。

var q1 = from v in root.Sequence
         where v.CurrentType == ChoiceEnum.Type1
         select v.Type1;

または、クエリをラップするメソッドをRootに作成することもできます。

于 2009-12-24T22:24:29.740 に答える
1

Linq2Xsdは、xsd:choice要素がある場合にのみシーケンスでトリップします。

幸い、使用しているAmazon XSDのxsd:choiceを削除することができました(MerchantOrderIDを使用していませんでした)。これにより、シーケンスをToString()xmlのに適切に保存できました。

            <xsd:choice>                                <--- removed line
                <xsd:element ref="AmazonOrderID"/>
                <xsd:element ref="MerchantOrderID"/>    <--- removed line
            </xsd:choice>                               <--- removed line

            <xsd:element name="ActionType" minOccurs="0" maxOccurs="1">
                <xsd:simpleType>
                    <xsd:restriction base="xsd:string">
                        <xsd:enumeration value="Refund"/>
                        <xsd:enumeration value="Cancel"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:element> 

生成されたコードは、コンストラクターにこれを正しく持ち、順序を保持します

contentModel = new SequenceContentModelEntity(
               new NamedContentModelEntity(XName.Get("AmazonOrderID", "")), 
               new NamedContentModelEntity(XName.Get("ActionType", "")), 
               new NamedContentModelEntity(XName.Get("CODCollectionMethod", "")), 
               new NamedContentModelEntity(XName.Get("AdjustedItem", "")));

自分でサブクラス化することで手動でこれを行うこともできるかもしれませんが、これがxsd:choiceでどのように機能するかはわかりません。これはここで説明されていますが、私はそれをテストしていません。

于 2014-03-12T18:54:52.630 に答える