3

XML スキーマ定義ツールを使用して、次のスキーマから CS コードを生成しようとしています:

A.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:complexType name="Bar">
        <xs:sequence>
            <xs:element name="v" type="xs:double"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="Base"/>
    <xs:element name="root" type="Base" />
</xs:schema>

B.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns1="v2" targetNamespace="v2" elementFormDefault="qualified">
    <xs:import schemaLocation="A.xsd"/>
    <xs:complexType name="Derived">
        <xs:complexContent>
            <xs:extension base="Base">
                <xs:sequence>
                    <xs:element name="b" type="Bar"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
</xs:schema>

次のように xsd.exe スキーマ コンパイラを実行します。

xsd.exe A.xsd B.xsd /c

B_A.cs ファイルを取得します (大量のコードです。自由に再生成してください)。

2 つの予期しない動作があります。

シリアル化: Derived 型の Bar のインスタンスをシリアル化する場合:

    XmlSerializer serializer = new XmlSerializer(typeof(Base));
    Derived d = new Derived();
    d.b = new Bar();
    d.b.v = 12.123;
    serializer.Serialize(Console.Out, d);

あなたはこれを得る:

<?xml version="1.0" encoding="ibm850"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:q1="v2" xsi:type="q1:Derived">
  <q1:b>
    <q1:v>12.123</q1:v>
  </q1:b>
</root>

bのv要素はq1で始まる名前空間であるため、B.xsdでは検証されません。(私が信じている)正しいように、プレフィックスを取り除きます。

同様に、その逆です。このインスタンス ドキュメントを使用すると、次のことが検証されます。

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:q1="v2" xsi:schemaLocation="v2 B.xsd" xsi:type="q1:Derived">
  <q1:b>
    <v>12.123</v>
  </q1:b>
</root>

次のように、生成されたコードでデシリアライズしてみてください。

    XmlSerializer serializer = new XmlSerializer(typeof(Base));
    Bar p = (Bar)serializer.Deserialize(new FileStream(@"..\..\test.xml", FileMode.Open));
    Console.Out.WriteLine(p.v);

v はデフォルトで初期化されているため、0.0 の出力が得られます。インスタンス ドキュメントの v 要素に q1: プレフィックスを追加すると、機能しますが、有効ではありません。

これが XML スキーマ定義ツールのせいであることに同意する人はいますか? 適切なシリアライゼーション コードを生成しているとは思えませんが、ツールのせいにするのは難しいです。Namespace="" を含む XmlElement 属性を v に追加すると機能しますが、生成されたコードを変更していますが、これは望ましくありません (私が作業しているプロジェクトは、ビルドの一部としてコードを生成します。変更することになっています)。

これを回避する方法はありますか?

4

1 に答える 1

0

さて、私は私が使用できると思うものを持っています-別のcsモジュールのBar部分クラスにXmlRootAttribute(Namespace = "")を追加します。

于 2012-10-28T21:32:49.757 に答える