17

「true」または「false」ではなく、「yes」または「no」としてブール値フラグを想定している別のプログラムに xml を送信しています。

次のように定義されたクラスがあります。

[XmlRoot()]
public class Foo {
    public bool Bar { get; set; }
}

シリアル化すると、出力は次のようになります。

<Foo><Bar>true</Bar></Foo>

しかし、私はそれがこれであることを望みます:

<Foo><Bar>yes</Bar></Foo>

連載の時にやってもいいですか?これに頼る必要はありません。

[XmlRoot()]
public class Foo {
    [XmlIgnore()]
    public bool Bar { get; set; }

    [XmlElement("Bar")]
    public string BarXml { get { return (Bar) ? "yes" : "no"; } }
}

このデータを再びデシリアライズできるようにしたいことに注意してください。

4

7 に答える 7

8

とてもシンプルです。サロゲート プロパティを使用します。実際のプロパティに XmlIgnore を適用します。サロゲートは文字列であり、要素名のオーバーライドを受け取る XmlElement 属性を使用する必要があります。オーバーライドで実際のプロパティの名前を指定します。サロゲート プロパティは、実際のプロパティの値に基づいて異なる方法でシリアル化されます。また、Surrogate のセッターを提供する必要があります。セッターは、シリアル化された値に関係なく、実際のプロパティを適切に設定する必要があります。つまり、双方向に進む必要があります。

をちょきちょきと切る:

    public class SomeType 
    {

        [XmlElement]
        public int IntValue;

        [XmlIgnore]
        public bool Value;

        [XmlElement("Value")]
        public string Value_Surrogate {
            get { return (Value)? "Yes, definitely!":"Absolutely NOT!"; }
            set { Value= (value=="Yes, definitely!"); }
        }

    }

完全なコンパイル可能なソースの例については、ここをクリックしてください。

于 2009-03-09T05:37:28.917 に答える
3

ブール値を「yes」または「no」としてシリアル化すると、データ型がブール値からまったく変更されます。代わりに、ブール値を評価し、そのデータ型に応じて「はい」または「いいえ」を返す別のプロパティを追加できますか? 戻り値の型をそれらの値のみを指定する列挙型にすることで、「はい」または「いいえ」を強制することもできます。

public YesOrNo DoYouLoveIt
{
    get { return boolToEvaluate ? YesOrNo.Yes : YesOrNo.No; }
}

それはやり過ぎかもしれませんが、あなたのニーズに答えるかもしれません。このような単純な値の列挙型を使用する唯一の理由は、値を制限するのではなく、任意の文字列を許可することです。

于 2009-03-09T05:18:50.913 に答える
2

プロパティ メソッドを使用しますが、文字列が yes または no に等しいかどうかを確認する代わりに、文字列が (大文字と小文字を区別しない) "YT1" で始まるかどうかを確認することを好みます。これにより、ファイルに true、True、t、T、y、Y、yes、Yes、1 などを含めることができます。これらはすべて true と評価されます。false は false、False、f、F、n、N、no、No、0 などと指定できますが、true に一致しないものはすべて false と評価されます。

于 2012-08-30T00:19:53.430 に答える
0

@Blorgbeard: オブジェクト クラスにこれらの YesNo クラスが複数ある場合は、必ず要素全体を読んでください。

public void ReadXml(XmlReader reader)
{
    string element = reader.ReadOuterXml();
    int startIndex = element.IndexOf('>') + 1;
    int length = element.LastIndexOf('<') - startIndex;

    string text = (element.Substring(startIndex, length).ToLowerInvariant();

    Value = (text == "yes");
}

そうしないと、問題が発生する可能性があります。

ReadXml メソッドは、WriteXml メソッドによって書き込まれた情報を使用してオブジェクトを再構成する必要があります。

このメソッドが呼び出されると、型の情報をラップする要素の先頭にリーダーが配置されます。つまり、シリアル化されたオブジェクトの開始を示す開始タグの直前です。このメソッドが戻るとき、すべてのコンテンツを含め、要素全体を最初から最後まで読み取っている必要があります。WriteXml メソッドとは異なり、フレームワークはラッパー要素を自動的に処理しません。実装ではそうする必要があります。これらの配置規則に従わないと、コードで予期しない実行時例外が生成されたり、データが破損したりする可能性があります。

于 2012-11-26T08:44:41.523 に答える
0

プロパティの例は、おそらく最も簡単な方法です。それが役立つ場合は、属性が背後のクラスに ISerializable を実装しているため、それをパブリック プロパティにする必要はないと思います。逆シリアル化を有効にするには、実装するだけでよいはずですset { Bar = value == "yes"; }

于 2009-03-09T05:38:10.413 に答える
-2

あなたがしなければならないことは、表示の問題のように聞こえます。アプリケーションが許可する場合は、データ型をブール値のままにし、ユーザー インターフェイスに Yes/No を表示する方がよいでしょう。

于 2009-03-09T05:23:20.170 に答える