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 文件(很多代码,随意重新生成自己)。

有两种意想不到的行为。

序列化:如果您序列化 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,它可以工作,但现在我正在修改生成的代码,这是不可取的(我正在工作的项目生成代码作为构建的一部分 - 我们不是应该改变它)。

有什么想法可以解决这个问题吗?

4

1 回答 1

0

好吧,我有一些我认为可以使用的东西 - 我将在单独的 cs 模块中将 XmlRootAttribute(Namespace="") 添加到 Bar 部分类。

于 2012-10-28T21:32:49.757 回答