我试图使用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文件(很多代码,可以自己重新生成)。
有两种意想不到的行为。
序列化:
如果序列化派生类型的条的实例:
    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.xsd验证,因为b中的v元素的前缀是q1。去掉前缀,它会验证,因为(我相信)是正确的。
同样,反过来。以这个实例文档为例,它验证:
<?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模式定义工具的错误吗?我不相信它生成了正确的序列化代码,但很难责怪工具。如果我们将名称空间为“”的xmlement属性添加到v中,它可以工作,但现在我正在修改生成的代码,这是不可取的(我正在工作的项目将生成代码作为构建的一部分-我们不应该更改它)。
有什么办法可以解决这个问题吗?

最佳答案

好吧,我有一些我认为可以使用的东西-我将在一个单独的cs模块中向bar部分类添加一个xmlrootattribute(namespace=“)。

10-05 17:54