C# と .NET 4.5 では、非常に効果的な DataContract シリアル化による XML 生成/解析を実装中です。ただし、いくつかの状況で多くの問題に遭遇しました。誰かが私を助けてくれることを願っています.
関連するクラスは次の 5 つです (さらにいくつかの埋め込みオブジェクト)。
[DataContract]
public abstract class ItemList<T> : List<T>, IList
{
.....
}
[DataContract]
public class CashFlowList : ItemList<CashFlow>
{
.....
}
[DataContract]
public class CashFlow : ItemList<CashFlowPayment>
{
.....
}
[DataContract]
public class CashFlowPayment : ListItem, IDataImportExport
{
.....
}
[DataContract]
public abstract class ListItem : System.IComparable, IList
{
.....
}
(CashFlowList 型で) DataContractSerializer を使用すると、結果の XML は次のようになります。
<CashFlowList xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/FinancialData">
<_items>
<CashFlow>
<_items>
<CashFlowPayment>
<ID>-1</ID>
<ProbDist xmlns:d6p1="http://schemas.datacontract.org/2004/07/ProbabilityDistributions" i:nil="true" />
<UseProbabilityDistribution>true</UseProbabilityDistribution>
<ValidFrom>0001-01-01T00:00:00</ValidFrom>
<ValidThrough>9999-12-31T23:59:59.9999999</ValidThrough>
<Amount>4500</Amount>
<Ccy i:nil="true" />
<Date>2012-02-03T00:00:00</Date>
<DaysFromStartDate>-1</DaysFromStartDate>
</CashFlowPayment>
<CashFlowPayment>
<ID>-1</ID>
<ProbDist xmlns:d6p1="http://schemas.datacontract.org/2004/07/ProbabilityDistributions" i:nil="true" />
<UseProbabilityDistribution>true</UseProbabilityDistribution>
<ValidFrom>0001-01-01T00:00:00</ValidFrom>
<ValidThrough>9999-12-31T23:59:59.9999999</ValidThrough>
<Amount>-30000</Amount>
<Ccy i:nil="true" />
<Date>2013-04-10T00:00:00+02:00</Date>
<DaysFromStartDate>465</DaysFromStartDate>
<DaysUntilEndDate>-1</DaysUntilEndDate>
<IsPerpetual>false</IsPerpetual>
<PaymentType>Unknown</PaymentType>
<Schedule xmlns:d6p1="http://schemas.datacontract.org/2004/07/Schedules" i:nil="true" />
</CashFlowPayment>
<CashFlowPayment i:nil="true" />
<CashFlowPayment i:nil="true" />
</_items>
<_size>2</_size>
<_version>3</_version>
<ID>-1</ID>
<Name></Name>
<ProbDist xmlns:d4p1="http://schemas.datacontract.org/2004/07/ProbabilityDistributions" i:nil="true" />
<UseProbability>false</UseProbability>
<ValidFrom>0001-01-01T00:00:00</ValidFrom>
<ValidThrough>9999-12-31T23:59:59.9999999</ValidThrough>
<BaseCCY></BaseCCY>
..............................
<StartDate>2012-05-09T00:00:00</StartDate>
<SumOfNegativePayments>-30000</SumOfNegativePayments>
<SumOfPositivePayments>4500</SumOfPositivePayments>
<ValueDate>0001-01-01T00:00:00</ValueDate>
<XMLCashFlowElementName i:nil="true" />
<XMLPaymentElementName i:nil="true" />
<XMLPaymentsElementName i:nil="true" />
</CashFlow>
<CashFlow i:nil="true" />
<CashFlow i:nil="true" />
<CashFlow i:nil="true" />
</_items>
<_size>1</_size>
<_version>1</_version>
<ID>-1</ID>
<Name></Name>
<ProbDist xmlns:d2p1="http://schemas.datacontract.org/2004/07/ProbabilityDistributions" i:nil="true" />
<UseProbability>false</UseProbability>
<ValidFrom>0001-01-01T00:00:00</ValidFrom>
<ValidThrough>9999-12-31T23:59:59.9999999</ValidThrough>
</CashFlowList>
生成された XML は正しいですが、いくつかの癖があります。まず、シリアライザーが出力を管理するために必要だと思われる <_items> 要素です。次に、各コレクション (<_items> 要素内) には常に最低 4 つの子要素があることがわかります。たとえば、別の CashFlow を外側に追加すると、要素は 2 つだけになります。その理由と回避方法はありますか?それ ?
1 つまたは複数の [DataContract] 属性を [CollectionDataContract] に置き換えると、属性内に設定されているプロパティに関係なく、期待どおりに文法的に正しい XML 出力が生成されますが、[CollectionDataContract] 属性を持つクラスごとに、コレクションアイテムのみが生成されます。 output - クラス内の通常のプロパティではありません。つまり、例は次のようになります。
<CashFlowList xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/FinancialData">
<CashFlow>
<CashFlowPayment>
....
</CashFlowPayment>
</CashFlow>
</CashFlowList>
上記の例では、次の要素 (外側の CashFlowList オブジェクト内) が無視されています。
<ID>-1</ID>
<Name></Name>
<ProbDist xmlns:d2p1="http://schemas.datacontract.org/2004/07/ProbabilityDistributions" i:nil="true" />
<UseProbability>false</UseProbability>
<ValidFrom>0001-01-01T00:00:00</ValidFrom>
<ValidThrough>9999-12-31T23:59:59.9999999</ValidThrough>
したがって、私の質問は、これが設計によるものであり、避けられないかどうかです。つまり、[CollectionDataContract] 属性を使用するときに、コレクションから派生したクラスを出力し、出力に追加のプロパティを含めることができますか?
興味深いことに、[CollectionDataContract] 属性が使用されている場合、XsdDataContractExporter クラスを使用して、対応する XSD を問題なく生成/取得できます (ただし、プロパティがないために XML は不完全です)。ただし、[DataContract] 属性を使用すると、XSD を生成できません (CanExport メソッドで失敗します)。ただし、XML は正確で完全ですが、特に判読できません。
したがって、これに関する洞察や考えを本当に感謝します。
よろしくお願いいたします。
マイケル