tags:

views:

1452

answers:

5

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

    <?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"&gt;
    <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.

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

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.

Thanks in advance Freggel

+1  A: 

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.

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"&gt;
  <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>
nick_alot
A: 

Yes Off course I'm aware of that alternative (solution) but I'm working with industrial standards which I can't change.

But thanks for your response nick_alot.

freggel
Next time, you can add a comment to the answer to your question.
Gamecat
@Gamecat: Not until the OP gets 39 more points.
Chris Jester-Young
+1  A: 

Hi, 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):

 ...
  <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> ...
A: 

Does anyone have a solution for this?

I am facing the same issue where the XSD was given to me by a vendor and I cannot change it ... and I used XSD.exe to create the dataset. And when I try to create an instance of it to try and import some XML data ... I get the same error message.

Additionally, I tried using the XSD.exe to generate classes instead of a dataset as well. And in using the classes, I ran into an issue where I cannot copy the data from either the XML file or a generic untyped dataset into this class. I rather not write all of the code to match each data field as I am sure there will be mistakes and possible unforeseen data conversion problems in the future.

Any suggestions???

A: 

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.

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.

Good luck!