【问题标题】:XSD class generation nested tables problemXSD类生成嵌套表问题
【发布时间】:2010-09-28 16:28:00
【问题描述】:

目前我在从具有重复元素的 xsd 生成类文件时遇到问题。我在 VS2005 SP1 中使用自定义工具“MsDatasetGenerator”,从 xsd 为 c# 创建一个类型化的数据集。我正在尝试通过此架构解析 xml

    <?xml version="1.0" encoding=\"utf-8\"?>
<xs:schema id="XSDobject" targetNamespace="http://tempuri.org/XSDobject.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XSDobject.xsd" xmlns:mstns="http://tempuri.org/XSDobject.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="order">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="contact">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="name" type="xs:string" />
                            <xs:element name="phone" type="xs:string" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="buyer">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="contact">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="name" type="xs:string" />
                                        <xs:element name="phone" type="xs:string" />
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

但我收到以下错误“同一张表'contact'不能是两个嵌套关系中的子表。

XSD 可以正确编译,但它是无法处理重复表的类型化数据集。现在我也测试了 xsd.exe 工具,但它似乎生成与 msdatasetgenerator 相同的代码。我还尝试了一些第三方代码生成器工具,例如 XSD2Code、CodeXS、AltovaXmlSpy,但我无法让它与嵌套元素一起使用。

另外,我可以在输入和输出处使用 xslt 转换来解决问题,但这会降低我的性能。

所以现在我问是否有人可以帮助我为 VS2005 提供一个好的解决方案,或者知道可以处理这个问题的好的 xsd 类生成器。如果它作为数组或列表工作,它不一定是类型化的数据集,只要它易于序列化和反序列化,它也是完美的。

提前致谢 弗雷格尔

【问题讨论】:

    标签: c# xml .net-2.0 xsd


    【解决方案1】:

    我遇到了同样的问题.. 如果性能不是问题,您可以使用 XSLT 重命名具有相同名称的“子”表(即结果名称是表名与其父级的串联):

     ...
      <xsl:template match="*">
         <xsl:param name="parentElm">
           <xsl:value-of select="name(..)" />
         </xsl:param>
         <xsl:choose>
           <xsl:when test="local-name() = 'Contact'">
             <xsl:element name="{concat('Contact',$parentElm)}">
               <xsl:apply-templates select="@* | node()" />
             </xsl:element>
           </xsl:when> <xsl:otherwise>
             <xsl:element name="{local-name()}">
               <xsl:copy-of select="@*" />
               <xsl:apply-templates select="@* | node()" />
             </xsl:element>
           </xsl:otherwise>
         </xsl:choose>   </xsl:template> ...
    

    【讨论】:

      【解决方案2】:

      我建议对模式项进行简单的重命名,并使用分组(如下所示)或 xsd 包含(如果您需要这种复杂类型用于其他模式)。如果您对名称没有硬性要求,这应该可以解决问题。

      根据经验,我认为可能的工具不适用于您示例中的重复命名。

      这样的事情可能会奏效:

      <?xml version="1.0" encoding="utf-8"?>
      <xs:schema id="XSDobject" targetNamespace="http://tempuri.org/XSDobject.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XSDobject.xsd" xmlns:mstns="http://tempuri.org/XSDobject.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:group name="Contact">
          <xs:sequence>
            <xs:element name="name" type="xs:string" />
            <xs:element name="phone" type="xs:string" />
          </xs:sequence>
        </xs:group>
        <xs:element name="order">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="OrderContact">
                <xs:complexType>
                  <xs:sequence>
                    <xs:group ref="Contact"/>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
              <xs:element name="buyer">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="BuyerContact">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:group ref="Contact"/>
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:schema>
      

      【讨论】:

        【解决方案3】:

        也许您可以使用 xsd:import / xsd:include 将 xsd 拆分为多个文件,然后使用 xsd.exe 编译每个文件。我认为您可以在使用 xsd.exe 时指定生成代码的名称空间。

        几年前我曾从 xsd:s 生成类,出于某种原因,我决定使用 xsdobjgen.exe 而不是 xsd.exe。

        祝你好运!

        【讨论】:

          【解决方案4】:

          看看我对这个项目的解决方案。

          The same table 'name' cannot be the child table in two nested relations

          我建议在架构中使用“ref”来引用“重复”元素。

          【讨论】:

            猜你喜欢
            • 2019-07-16
            • 1970-01-01
            • 2023-03-19
            • 1970-01-01
            • 2012-10-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-06-06
            相关资源
            最近更新 更多