Question

I'm attempting to deserialize the XML (below)

I'm stuck due to the "non-standard" structure of the XML. Instead of the normal way to serialize a Products collection, ie: a parent with many child elements. They have many parent elements each with a single child element.

My issue is that due to this unusual array structure (I suspect due to a bug), I can't figure out how to set the attributes ie:[XMLArrayItem] so that I can extract meaningful data.

Note: The XML is an HTTPResponse from a public 3rd party. (So I can't get them to change it.)

Specifically: Instead of a < Products> parent with many < Product> elements.

The < betType> node has multiple < Products> parent elements each with a single < Product> child element.

You have total freedom to create whatever classes with whatever properties are needed. Clearly the solution needs BetType & Product classes. I've tried both with & without a Products class.

<rootnode>
:
  <bet_types>
    <bet_type id="105">
      <name>Exacta</name>
      <products>
        <product id="17">
            <name>STAB</name>
            <max_stake>10000</max_stake>
            <allow_multiple>0</allow_multiple>
            <allow_flexi>1</allow_flexi>
            <product_default>1</product_default>
        </product>
      </products>
      <products>
        <product id="25">
              <name>NSW</name>
              <max_stake>10000</max_stake>
              <allow_multiple>0</allow_multiple>
              <allow_flexi>1</allow_flexi>
         </product>
      </products>
    </bet_type>

    <bet_type id="107">
      <name>Quinella</name>
      <products>
        <product id="18">
            <name>STAB</name>
            <max_stake>10000</max_stake>
            <allow_multiple>0</allow_multiple>
            <allow_flexi>1</allow_flexi>
            <product_default>1</product_default>
        </product>
      </products>
      <products>
        <product id="26">
            <name>NSW</name>
            <max_stake>10000</max_stake>
            <allow_multiple>0</allow_multiple>
            <allow_flexi>1</allow_flexi>
        </product>
      </products>
    </bet_type>
:
</rootnode>

Ideally we could use the .Net C# xmlSerializer as I'm using it for all the other calls. And this sample is a small fragment nested deep in the HTTPResponse.

One possible alternative be to use XSLT to reformat it, but am hoping there is a way to do it with attributes. I think it is cleaner, & I'm unsure how I'd write the XSLT to do it.

Note: Alternatively if you can suggest a way to "not produce" a Node for the parent array & just create the node for each array item, that would help. As one of the approaches I've tried got really close. But I still had a "Products" node that was a parent to the multiple Products nodes that each contained a single Product node.

Thanks for your help.

Was it helpful?

Solution

When in doubt, create an XML schema for your XML document and run xsd.exe on it. You can then look at (or use) the generated code.

To get you started, here's an XML schema that matches the XML you posted above. Run xsd.exe /c /f /n:Your.Namespace.Here FileName.xsd to generate the code.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" >
  <xs:element name="rootnode">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="bet_types">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="bet_type" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="name" type="xs:string" />
                    <xs:element name="products" minOccurs="0" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="product">
                            <xs:complexType>
                              <xs:sequence>
                                <xs:element name="name" type="xs:string" />
                                <xs:element name="max_stake" type="xs:int" />
                                <xs:element name="allow_multiple" type="xs:int" />
                                <xs:element name="allow_flexi" type="xs:int" />
                                <xs:element name="product_default" type="xs:int" minOccurs="0" />
                              </xs:sequence>
                              <xs:attribute name="id" type="xs:int" use="required" />
                            </xs:complexType>                            
                          </xs:element>
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="id" type="xs:int" use="required" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top