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 に追加すると機能しますが、生成されたコードを変更していますが、これは望ましくありません (私が作業しているプロジェクトは、ビルドの一部としてコードを生成します。変更することになっています)。
これを回避する方法はありますか?