2013-02-21 8 views
5

C#でブックインポートツール用のONIXを作成しようとしています。私はXsd2Codeを使ってクラスを作成し始め、いくつかの調整をしてもデシリアライズ時にエラーを発生させないすべてのプロパティを持つ巨大なファイルを取得しました。CのValueプロパティを使用してXmlから列挙型を逆シリアル化します。

私は、一度に要素全体をデシリアライズし、メモリ内の大きなオブジェクトにデシリアライズしてから、データベースに保存するなどの作業を行います。

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

ここでProductオブジェクトのプロパティでなければなりませんクラスのいずれかです:私はこのラインにあなたの注意を向けたいと思い

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... 

私の問題は、すべてのフィールドが正しいにデシリアライズy Enumを除く。

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(Enumのデフォルト)を表示します。

このValueプロパティは、いくつかの型(文字列)では使用できますが、列挙型では使用できないということについては、SOおよびWeb検索に関するすべての質問を使い果たしました。何か不足していますか?

申し訳ありませんが長い質問とコードです。誰もがこの問題に出すことができる光を感謝します。今一日中それについた。

答えて

1

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

+0

これは動作します!私はそれを前に試したことを誓うことができました。これはXML要素の値としてどのプロパティを埋め込むかをデシリアライゼーションライブラリに知らせる属性です。 –

+0

私のために働かない。 –

+0

クレイジー、私はONIXにも取り組んでいます!この同じことは、単一のEnum値のために私にとってもうまくいきます。列挙型の配列を脱灰することでどんな運がありますか? List91 []など? –

2

この試してみてください。私も最初XmlText属性を持つメンバーを飾るにしようとしたが、次の例外だった

  1. :ので

    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; } 
    } 
    

    [UPDATE]

    を発生:

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

  2. とあなたは答えに私の最初のアプローチを避けたい、

真の解決策は、ValueXmlText属性を適用する以外に、他のすべてのメンバーが飾られるべき、ということですXmlIgnoreAttributeXmlTextを単独で使用することは、結果が他のメンバーの存在に依存するため、保証された解決策ではないと私は信じている。

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; } 
} 
+0

投票しましたが、これもうまく機能しますが直接的な方法はありません。 ONIX仕様には約200種類があるので、それぞれのケースに追加のプロパティを導入するのは本当に好きではありません。 –

+0

@CristiCotovan、私はpbzの答えを試しても 'InvalidOperationException'を持っています。彼の答えは私の最初の試行でしたが、失敗しました(それでも失敗します)ので、回避策を探しました。 –

+0

それはここで働く、なぜあなたのために失敗したのか分からない。私はそれがより清潔になり、このように好むので、上に他のものを追加します(各Enumバリアントを記述し、Enum値ごとにユーザーフレンドリーな意味を表示するためにReflectionを使用して抽出するなど)。 –

関連する問題