我正在尝试使用XML Schema Definition Tool从以下架构生成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文件(很多代码,可以自己重新生成)。
有两个意想不到的行为。
序列化: 如果序列化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);
得到0.0输出,因为默认初始化为v。将q1:前缀添加到实例文档的v元素,它可以工作,但无效。
有人会同意这是XML Schema定义工具的错吗?我不相信它会生成正确的序列化代码,但很难归咎于这些工具。如果我们将带有Namespace =“”的XmlElement属性添加到v,它可以工作,但现在我正在修改生成的代码,这是不可取的(我正在工作的项目生成代码作为构建的一部分 - 我们不是应该改变它。)
我有什么想法可以解决这个问题吗?
答案 0 :(得分:0)
好吧,我有一些我认为可以使用的东西 - 我会在单独的cs模块中向Bar分部类添加一个XmlRootAttribute(Namespace =“”)。