XSD类生成嵌套表问题

时间:2022-12-30 17:19:25

Currently I'm having a problem with generating class files from a xsd with repeating elements. I’m using the custom tool ‘MsDatasetGenerator’ in VS2005 SP1 witch create a typed dataset from the xsd for c#. I’m trying to parse the xml by this schema

目前我遇到了从带有重复元素的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>

But I get following error “The same table 'contact' cannot be the child table in two nested relations.

但我得到以下错误“同一个表'联系人'不能是两个嵌套关系中的子表。”

The XSD compiles correctly but it’s the typed dataset that can’t handle repeating tables. Now I have tested also the xsd.exe tool but it seems to generate the same code as the msdatasetgenerator. I also tried some third party code generator tools like XSD2Code, CodeXS, AltovaXmlSpy but also I can’t get it to work with nested elements.

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

Alternatively I could solve the problem with xslt transformation at the input and the output but it would cost me a lot of performance.

或者,我可以在输入和输出处解决xslt转换的问题,但这会花费我很多性能。

So now I’m asking if someone could help me with a good solution for VS2005, or know good xsd class generator that can handle this problem. It doesn’t have to be a typed dataset if it works as an array or a list it is also perfect as long it is easy to serializing and deserializing it.

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

Thanks in advance Freggel

在此先感谢Freggel

4 个解决方案

#1


2  

I had the same problem.. if performances are not an issue, you can use XSLT to rename the "child" tables that have the same name, (i.e. the resulting name is the concatenation of table name and its parent):

我遇到了同样的问题..如果性能不是问题,你可以使用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


1  

I would suggest a simple renaming of the schema items, plus the usage of grouping (shown below) or xsd includes (if you need this complex type for other schemas). This should solve to problem if you have no hard requirment on the names.

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

From experience, I don't think may tools will work with the repeated naming in your example.

根据经验,我认为工具不会与您示例中的重复命名一起使用。

Something like this may do the trick:

像这样的东西可以做到这一点:

<?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


0  

Maybe you can use the xsd:import / xsd:include to split the xsd into several files, then use xsd.exe to compile each. I think you can specify the namespace to generate the code to when working with xsd.exe.

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

I worked with generating classes from xsd:s a couple of years ago, and for some reason I decided on using xsdobjgen.exe instead of xsd.exe.

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

Good luck!

祝你好运!

#4


0  

Look at my solution for this item.

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

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

同一个表'name'不能是两个嵌套关系中的子表

I suggest using 'ref' in your schema to refer to the 'duplicate' elements.

我建议在架构中使用'ref'来引用'duplicate'元素。

#1


2  

I had the same problem.. if performances are not an issue, you can use XSLT to rename the "child" tables that have the same name, (i.e. the resulting name is the concatenation of table name and its parent):

我遇到了同样的问题..如果性能不是问题,你可以使用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


1  

I would suggest a simple renaming of the schema items, plus the usage of grouping (shown below) or xsd includes (if you need this complex type for other schemas). This should solve to problem if you have no hard requirment on the names.

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

From experience, I don't think may tools will work with the repeated naming in your example.

根据经验,我认为工具不会与您示例中的重复命名一起使用。

Something like this may do the trick:

像这样的东西可以做到这一点:

<?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


0  

Maybe you can use the xsd:import / xsd:include to split the xsd into several files, then use xsd.exe to compile each. I think you can specify the namespace to generate the code to when working with xsd.exe.

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

I worked with generating classes from xsd:s a couple of years ago, and for some reason I decided on using xsdobjgen.exe instead of xsd.exe.

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

Good luck!

祝你好运!

#4


0  

Look at my solution for this item.

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

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

同一个表'name'不能是两个嵌套关系中的子表

I suggest using 'ref' in your schema to refer to the 'duplicate' elements.

我建议在架构中使用'ref'来引用'duplicate'元素。