3

给定 XSD,例如:

  <xs:complexType name="accident">
    <xs:sequence>
      <xs:element name="NAME" type="xs:string" />
      <xs:element name="DESCRIPTION" type="xs:string" />
      <xs:element name="CREATIONDATE" type="xs:dateTime" />
    </xs:sequence>
  </xs:complexType>

  <xs:element name="accidents">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="accident" type="accident" maxOccurs="unbounded" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

我希望 XML 像:

<?xml version="1.0" encoding="UTF-8"?>
<accidents>
  <accident>
    <NAME>Accident 123</NAME>
    <DESCRIPTION>Car crash</DESCRIPTION>
    <CREATIONDATE>2016-01-20T12:08:00+00:00</CREATIONDATE>
  </accident>
</accidents>

我使用 XSD2Code 生成 C# 类,因此我可以轻松地从 Web 服务反序列化 XML。但他们工作不正常——他们像我的例子一样成功地加载了一个测试 XML,但accident元素为零。

所以我决定扭转这个过程:

    accidents aa = new accidents();
    accident a = new accident();
    a.NAME = "test";
    aa.accident.Add(a);
    aa.SaveToFile("accidents.xml");

这发出了以下 XML:

<?xml version="1.0"?>
<accidents xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <accident>
    <accident>
      <NAME>test</NAME>
      <CREATIONDATE>0001-01-01T00:00:00</CREATIONDATE>
    </accident>
  </accident>
</accidents>

如果我尝试反序列化该 XML,它就可以正常工作。但请注意,有一个accident不正确的嵌套,我不知道它会这样做或如何修复它!

这似乎是一个类似的问题,但由于它没有引起太多关注并且不包括 XSD,我不确定:xsd2code 在序列化列表时创建额外的嵌套集合

4

2 回答 2

1

我在现场有点晚了,但不管怎样!

我自己一直在使用 Xsd2Code 来利用一些很酷的功能,但我发现它确实有一些烦人的怪癖。我同意您描述的这个问题看起来像一个错误。但是,我发现如果您的集合本身就是另一种复杂类型的子元素,问题就会消失。例如,如果您很高兴您的“事故”作为“报告”的属性存在,那么您将按如下方式更改您的架构:

 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:complexType name="accident">
    <xs:sequence>
      <xs:element name="NAME" type="xs:string" />
      <xs:element name="DESCRIPTION" type="xs:string" />
      <xs:element name="CREATIONDATE" type="xs:dateTime" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="accidents">
     <xs:sequence>
       <xs:element name="accident" type="accident" maxOccurs="unbounded" minOccurs="0"/>
     </xs:sequence>
  </xs:complexType>
  <xs:complexType name="report">
    <xs:sequence>
      <xs:element name="accidents" type="accidents"/>
    </xs:sequence>
  </xs:complexType>   
</xs:schema>

当您通过 Xsd2Code 工具运行它时,您会发现生成的代码将报告类型的事故属性创建为事故列表,并将按照您期望的方式进行序列化。

您的测试代码应该看起来更像这样:

        report r = new report();
        r.accidents = new List<accident>();
        accident a = new accident();
        a.NAME = "test";
        r.accidents.Add(a);
        r.SaveToFile("accidents.xml");

不幸的是,仍然会生成狡猾的事故类 - 这可能会给其他开发人员造成混淆,但有一种方法可以防止这种情况发生。首先,将事故事故complexType 定义放在一个文件意外事件.xsd 中。然后将报告定义放在report.xsd中,并带有引用意外事件.xsd的包含语句。仅通过 Xsd2Code 工具传递report.xsd 。畸形的事故类不会出现在生成的代码中。当然,这只是一个说明性示例 - 根据需要扩展。在没有修复的情况下,这对我来说是一个非常好的解决方案 - 希望它会满足您的需求。

于 2017-02-17T22:50:17.320 回答
0

您可以从在 XSD 中指定目标名称空间和显式限定标志开始。也就是说,将您的 xsd 转换为:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified"
         elementFormDefault="qualified"
         xmlns:xs="http://www.w3.org/2001/XMLSchema"
         targetNamespace="http://example.com/foo"
         xmlns="http://example.com/foo">

<xs:complexType name="accident">
  <xs:sequence>
    <xs:element name="NAME" type="xs:string" />
    <xs:element name="DESCRIPTION" type="xs:string" />
    <xs:element name="CREATIONDATE" type="xs:dateTime" />
  </xs:sequence>
</xs:complexType>

<xs:element name="accidents">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="accident" type="accident" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

</xs:schema>

和您的 XML 到:

<?xml version="1.0" encoding="UTF-8"?>
<accidents xmlns="http://example.com/foo"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://example.com/foo foo.xsd">
  <accident>
    <NAME>Accident 123</NAME>
    <DESCRIPTION>Car crash</DESCRIPTION>
    <CREATIONDATE>2016-01-20T12:08:00+00:00</CREATIONDATE>
  </accident>
</accidents>

(您需要将 xsd 文件另存为 foo.exe 以便上述参考工作)。

我不确定这是否能解决您的 XSD2Code 问题,但我已将此标头格式与 xsd.exe 一起用于许多等效(并且更复杂)的代码。它可以让您在 XML 中获得 Intellisense,也可能足以让 XSD2Code 正常运行。

于 2016-06-09T23:25:24.180 回答