XSD2Code类需要包含元素集合的重复命名元素

时间:2016-06-09 14:32:14

标签: c# xml xsd xsd2code

鉴于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 creates extra nested collection when serializing lists

2 个答案:

答案 0 :(得分: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正常运行。

答案 1 :(得分:0)

我现场有点迟到了,但无论如何都要去了!

我一直在使用Xsd2Code一段时间来利用一些很酷的功能,但我发现它确实有一些恼人的怪癖。我同意你描述的这个问题看起来像一个bug。但是我发现如果你的集合本身是另一个复杂类型的子元素,那么问题就会消失。如果您对自己的事故感到满意,那么#34;作为&#34;报告&#34;的财产存在例如,您可以按如下方式更改架构:

 <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");

不幸的是,仍然会产生狡猾的意外级别 - 这可能会引起其他开发人员的混淆,但有一种方法可以防止这种情况发生。   首先,将意外意外复杂类型定义放入a 文件, accident.xsd 。然后将报告定义放在 report.xsd 中 引用 accident.xsd 的include语句。只传递 report.xsd 通过Xsd2Code工具。格式错误的意外类不会出现在生成的代码中。这只是一个示例性的例子 - 根据需要进行扩展。在没有修复的情况下,这对我来说是一个非常好的解决方案 - 希望它能满足您的需求。