Simone
Simone

Reputation: 2430

XML Deserialization lose item of arrays

I have to deserialize an xml... Here the step I do.

  1. I generate the XSD from the xml with xsd xxx.xml;
  2. Two XSD are generated. So, I generate c# classes with xsd x1.xsd x2.xsd /classes
  3. A .cs file is generated with all necessary classes inside it. I check the file. Everything seems ok.. I have one array where I could have more than 1 result.
  4. In my code I have one xml to deserialize (the one I used to generate the xsd) and I deserialize it with this code:

    public static T Deserialize(Stream xml)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
    
        T objectDeserialized = null;
        using (StreamReader reader = new StreamReader(xml))
        {
            objectDeserialized = serializer.Deserialize(reader) as T;
        }
    
        return objectDeserialized;
    }
    

What I obtain is an array with just one element, but xml has two element (I have checked on debug).. What can be the problem?

UPDATE

Following the XML and the XSD...

XML:

<?xml version="1.0" encoding="UTF-8"?>
    <SELECT_CONFIGURATIONResponse xmlns="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo">
    <StoredProcedureResultSet0>
        <StoredProcedureResultSet0 xmlns="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION">
            <FlowId>653de913-a648-419f-85be-0e7ec93c2892</FlowId>
            <DestinationPath>C:\temp\IncomingFiles2</DestinationPath>
            <OriginPath>xxx</OriginPath>
            <DeleteAfterOperation>true</DeleteAfterOperation>
            <IntervalWatchFolder>150000000</IntervalWatchFolder>
            <SearchPattern>*.*</SearchPattern>
            <Recoverable>true</Recoverable>
            <FlowTypeId>1</FlowTypeId>
            <GatewayId>6be02fcc-ea98-4711-ab08-616a8e7be26a</GatewayId>
            <ServerAddress>sftp://127.0.0.1</ServerAddress>
            <PortNumber>22</PortNumber>
            <RetryCount>10</RetryCount>
            <Protocol_Id>1</Protocol_Id>
            <RequireAuthentication>true</RequireAuthentication>
            <RetryInterval>150000000</RetryInterval>
            <IntervalFileToRecover>150000000</IntervalFileToRecover>
            <ConfigurationId>544effad-d23c-404b-afe0-8c3c50d2fc50</ConfigurationId>
            <ServiceId>70472a23-404b-44d2-a191-d9650cdde3d6</ServiceId>
         </StoredProcedureResultSet0>
         <StoredProcedureResultSet0 xmlns="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION">
            <FlowId>73a39040-f4b2-470a-bfd2-cd09f6e91812</FlowId>
            <DestinationPath>C:\temp\IncomingFiles</DestinationPath>
            <OriginPath>Temp2</OriginPath>
            <DeleteAfterOperation>true</DeleteAfterOperation>
            <IntervalWatchFolder>150000000</IntervalWatchFolder>
            <SearchPattern>*.*</SearchPattern>
            <Recoverable>false</Recoverable>
            <FlowTypeId>1</FlowTypeId>
            <GatewayId>b6172429-8056-41cd-9db6-e0a403ba792a</GatewayId>
            <ServerAddress>ftp://127.0.0.1</ServerAddress>
            <PortNumber>21</PortNumber>
            <RetryCount>5</RetryCount>
            <Protocol_Id>2</Protocol_Id>
            <RequireAuthentication>false</RequireAuthentication>
            <RetryInterval>150000000</RetryInterval>
            <IntervalFileToRecover>150000000</IntervalFileToRecover>
            <ConfigurationId>544effad-d23c-404b-afe0-8c3c50d2fc50</ConfigurationId>
            <ServiceId>70472a23-404b-44d2-a191-d9650cdde3d6</ServiceId>
         </StoredProcedureResultSet0>
      </StoredProcedureResultSet0>
      <ReturnValue>0</ReturnValue>
</SELECT_CONFIGURATIONResponse>

The XSD 1:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="NewDataSet" targetNamespace="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo" xmlns:mstns="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo" xmlns="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:app1="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION">
  <xs:import namespace="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION" schemaLocation="xxx_app1.xsd" />
  <xs:element name="SELECT_CONFIGURATIONResponse">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ReturnValue" type="xs:string" minOccurs="0" />
        <xs:element name="StoredProcedureResultSet0" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element ref="app1:StoredProcedureResultSet0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="SELECT_CONFIGURATIONResponse" />
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

And the XSD 2:

<?xml version="1.0" standalone="yes"?>
<xs:schema targetNamespace="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION" xmlns:mstns="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo" xmlns="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:app1="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION">
  <xs:import namespace="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo" schemaLocation="xxx.xsd" />
  <xs:element name="StoredProcedureResultSet0">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="FlowId" type="xs:string" minOccurs="0" />
        <xs:element name="DestinationPath" type="xs:string" minOccurs="0" />
        <xs:element name="OriginPath" type="xs:string" minOccurs="0" />
        <xs:element name="DeleteAfterOperation" type="xs:string" minOccurs="0" />
        <xs:element name="IntervalWatchFolder" type="xs:string" minOccurs="0" />
        <xs:element name="SearchPattern" type="xs:string" minOccurs="0" />
        <xs:element name="Recoverable" type="xs:string" minOccurs="0" />
        <xs:element name="FlowTypeId" type="xs:string" minOccurs="0" />
        <xs:element name="GatewayId" type="xs:string" minOccurs="0" />
        <xs:element name="ServerAddress" type="xs:string" minOccurs="0" />
        <xs:element name="PortNumber" type="xs:string" minOccurs="0" />
        <xs:element name="RetryCount" type="xs:string" minOccurs="0" />
        <xs:element name="Protocol_Id" type="xs:string" minOccurs="0" />
        <xs:element name="RequireAuthentication" type="xs:string" minOccurs="0" />
        <xs:element name="RetryInterval" type="xs:string" minOccurs="0" />
        <xs:element name="IntervalFileToRecover" type="xs:string" minOccurs="0" />
        <xs:element name="ConfigurationId" type="xs:string" minOccurs="0" />
        <xs:element name="ServiceId" type="xs:string" minOccurs="0" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

The class generated has the following code:

...
[System.Xml.Serialization.XmlElementAttribute("StoredProcedureResultSet0")]
public SELECT_CONFIGURATIONResponseStoredProcedureResultSet0[] StoredProcedureResultSet0
{
    get
    {
        return this.storedProcedureResultSet0Field;
    }
    set
    {
       this.storedProcedureResultSet0Field = value;
    }
}
...

Upvotes: 1

Views: 269

Answers (2)

Jesse C. Slicer
Jesse C. Slicer

Reputation: 20157

Well, the XML doesn't validate against the schema posted:

ERROR: The element 'StoredProcedureResultSet0' in namespace
'http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo' has invalid child element
'StoredProcedureResultSet0' in namespace
'http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION'.
ERROR: The element 'SELECT_CONFIGURATIONResponse' in namespace
'http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo' has invalid child element 'ReturnValue'
in namespace 'http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo'. List of possible elements
expected: 'StoredProcedureResultSet0' in namespace
'http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo'.

Therefore, your XML or your XSD needs to change. I'd change the first.xsd appropriately:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="NewDataSet" targetNamespace="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo" xmlns:mstns="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo" xmlns="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:app1="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION">
  <xs:import namespace="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION" schemaLocation="xxx_app1.xsd" />
  <xs:element name="SELECT_CONFIGURATIONResponse">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="StoredProcedureResultSet0">
          <xs:complexType>
            <xs:sequence>
              <xs:element ref="app1:StoredProcedureResultSet0" minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="ReturnValue" type="xs:string" minOccurs="0" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="SELECT_CONFIGURATIONResponse" />
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

Regen your xsd classes and make minor changes to your code (collection moves up in hierarchy) and you're good to go.

Upvotes: 1

dbc
dbc

Reputation: 116731

The problem is that your XML does not match your XSD. Your XSD defines the following hierarchy:

public partial class SELECT_CONFIGURATIONResponse
{
     public string ReturnValue { get; set; }
     public SELECT_CONFIGURATIONResponseStoredProcedureResultSet0[] StoredProcedureResultSet0 { get; set; }
}

public partial class SELECT_CONFIGURATIONResponseStoredProcedureResultSet0
{
    public StoredProcedureResultSet0 StoredProcedureResultSet0 { get; set }
}

public partial class StoredProcedureResultSet0
{
    public string FlowId { get; set; }
    // Etc etc
}

I.e., your array is a property of the class CONFIGURATIONResponse and is used like this:

        var data = xml.LoadFromXML<SELECT_CONFIGURATIONResponse>();

        for (int i = 0; i < data.StoredProcedureResultSet0.Length; i++)
            Debug.WriteLine(data.StoredProcedureResultSet0[i].StoredProcedureResultSet0.FlowId);

However, your XML has the array on the INNER nested element, as if the classes were defined like this:

public partial class SELECT_CONFIGURATIONResponse
{
     public string ReturnValue { get; set; }
     public SELECT_CONFIGURATIONResponseStoredProcedureResultSet0 StoredProcedureResultSet0 { get; set; }
}

public partial class SELECT_CONFIGURATIONResponseStoredProcedureResultSet0
{
    public StoredProcedureResultSet0 StoredProcedureResultSet0[] { get; set }
}

public partial class StoredProcedureResultSet0
{
    public string FlowId { get; set; }
    // Etc etc
}

To fix the XML, you need to make it match the XSD as follows:

<?xml version="1.0" encoding="UTF-8"?>
    <SELECT_CONFIGURATIONResponse xmlns="http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo">
    <StoredProcedureResultSet0>
        <StoredProcedureResultSet0 xmlns="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION">
            <FlowId>653de913-a648-419f-85be-0e7ec93c2892</FlowId>
            <DestinationPath>C:\temp\IncomingFiles2</DestinationPath>
            <OriginPath>xxx</OriginPath>
            <DeleteAfterOperation>true</DeleteAfterOperation>
            <IntervalWatchFolder>150000000</IntervalWatchFolder>
            <SearchPattern>*.*</SearchPattern>
            <Recoverable>true</Recoverable>
            <FlowTypeId>1</FlowTypeId>
            <GatewayId>6be02fcc-ea98-4711-ab08-616a8e7be26a</GatewayId>
            <ServerAddress>sftp://127.0.0.1</ServerAddress>
            <PortNumber>22</PortNumber>
            <RetryCount>10</RetryCount>
            <Protocol_Id>1</Protocol_Id>
            <RequireAuthentication>true</RequireAuthentication>
            <RetryInterval>150000000</RetryInterval>
            <IntervalFileToRecover>150000000</IntervalFileToRecover>
            <ConfigurationId>544effad-d23c-404b-afe0-8c3c50d2fc50</ConfigurationId>
            <ServiceId>70472a23-404b-44d2-a191-d9650cdde3d6</ServiceId>
         </StoredProcedureResultSet0>
     </StoredProcedureResultSet0>
     <StoredProcedureResultSet0>
         <StoredProcedureResultSet0 xmlns="http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION">
            <FlowId>73a39040-f4b2-470a-bfd2-cd09f6e91812</FlowId>
            <DestinationPath>C:\temp\IncomingFiles</DestinationPath>
            <OriginPath>Temp2</OriginPath>
            <DeleteAfterOperation>true</DeleteAfterOperation>
            <IntervalWatchFolder>150000000</IntervalWatchFolder>
            <SearchPattern>*.*</SearchPattern>
            <Recoverable>false</Recoverable>
            <FlowTypeId>1</FlowTypeId>
            <GatewayId>b6172429-8056-41cd-9db6-e0a403ba792a</GatewayId>
            <ServerAddress>ftp://127.0.0.1</ServerAddress>
            <PortNumber>21</PortNumber>
            <RetryCount>5</RetryCount>
            <Protocol_Id>2</Protocol_Id>
            <RequireAuthentication>false</RequireAuthentication>
            <RetryInterval>150000000</RetryInterval>
            <IntervalFileToRecover>150000000</IntervalFileToRecover>
            <ConfigurationId>544effad-d23c-404b-afe0-8c3c50d2fc50</ConfigurationId>
            <ServiceId>70472a23-404b-44d2-a191-d9650cdde3d6</ServiceId>
         </StoredProcedureResultSet0>
      </StoredProcedureResultSet0>
      <ReturnValue>0</ReturnValue>
</SELECT_CONFIGURATIONResponse>

Upvotes: 1

Related Questions