5

C#で本のインポートツール用のONIXを作成しようとしています。Xsd2Codeを使用してクラスを作成することから始め、すべてのプロパティを含む巨大なファイルを取得しました。これらのファイルをいくつか調整した後、逆シリアル化してもエラーは発生しません。

要素全体を一度に逆シリアル化して、メモリ内の大きなオブジェクトに入れてから、それを使って何かを実行しようとしています(データベースに保存するなど)。

Xsd2Codeがクラスを生成する方法は、プロパティがたくさんあるという事実を除けば、少なくとも私にとっては少し奇妙です。

Productオブジェクトのプロパティである必要があるクラスの1つを次に示します。

public partial class NotificationType
{
    public NotificationTypeRefname refname { get; set; }
    public NotificationTypeShortname shortname { get; set; }

    public SourceTypeCode sourcetype { get; set; }

    public List1 Value { get; set; }
}

この行に注意を向けたいと思います。

    public List1 Value { get; set; }

「List1」は列挙型であり、次のように定義されます。

public enum List1
{
    [System.Xml.Serialization.XmlEnum("01")]
    Item01,

    [System.Xml.Serialization.XmlEnum("02")]
    Item02, etc...

私の問題は、逆シリアル化中に、列挙型を除いてすべてのフィールドが正しく逆シリアル化されることです。

XmlEnum( "NotificationType")などでプロパティを装飾してみました...何もありません!

これは私の逆シリアル化コードです:

var p = new Product();
XmlSerializer pserializer = new XmlSerializer(p.GetType());
object pDeserialized = pserializer.Deserialize(reader);
p = (Product) pDeserialized;

この要素はXMLで次のように表示されます。

<NotificationType>03</NotificationType>

ProductオブジェクトのC#にあるプロパティは次のとおりです。

public NotificationType NotificationType { get; set; }

これを次のように変更した場合:

public List1 NotificationType { get; set; }

デシリアライズでは「Item03」が正しく表示されます。つまり、XMLにあるものはすべて読み取られます。上記のようにそのままにしておくと、NotificationTypeクラスの'Value'プロパティが入力されることはなく、常にItem01(列挙型のデフォルト)が表示されます。

このValueプロパティが一部のタイプ(文字列)で機能するのに列挙型では機能しない理由について、SOおよびWeb検索で考えられるすべての質問を使い果たしました。私は何かが足りないのですか?

長い質問とコードでごめんなさい。この問題について誰もが当てることができる光に感謝します。一日中それで立ち往生しています。

4

2 に答える 2

2

これを試して:

public partial class NotificationType
{
    public NotificationTypeRefname refname { get; set; }
    public NotificationTypeShortname shortname { get; set; }
    public SourceTypeCode sourcetype { get; set; }

    public List1 Value { get {
        return (List1)Enum.Parse(typeof(List1), 
            Enum.GetName(typeof(List1), int.Parse(List1Value) - 1));
    }}

    [XmlText]
    public string List1Value { get; set; }
}

[アップデート]

以来:

  1. また、最初にメンバーを属性で装飾しようとしましたXmlTextが、次の例外が発生していました。

    タイプ'ConsoleApplication1.NotificationType'のオブジェクトをシリアル化できません。XmlTextメンバーのタイプ'ConsoleApplication1.NotificationType.Value'をConsoleApplication1.List1から文字列または文字列配列に変更することを検討してください。

  2. そして、あなたは答えの中で私の最初のアプローチを避けたいと思います、

実際の解決策は、XmlText属性をに適用する以外にValue、他のすべてのメンバーをで装飾する必要があるということXmlIgnoreAttributeです。XmlText結果は他のメンバーの存在に依存するため、単独で使用することは保証された解決策ではないと思います。

public class NotificationType
{
    [XmlIgnore] // required
    public NotificationTypeRefname refname { get; set; }
    [XmlIgnore] // required
    public NotificationTypeShortname shortname { get; set; }
    [XmlIgnore] // required
    public SourceTypeCode sourcetype { get; set; }

    [XmlText] // required
    public List1 Value { get; set; }
}
于 2013-02-21T13:22:52.583 に答える
1

プロパティに追加[System.Xml.Serialization.XmlTextAttribute()]してみてください。public List1 Value { get; set; }

于 2013-02-21T13:27:36.533 に答える