XML 反序列化会丢失数组项
本文关键字:数组 反序列化 XML | 更新日期: 2023-09-27 18:35:09
我必须反序列化一个 xml...这是我做的一步。
- 我用
xsd xxx.xml
从 xml 生成 XSD ; - 将生成两个 XSD。因此,我使用
xsd x1.xsd x2.xsd /classes
生成 c# 类 - 生成一个
.cs
文件,其中包含所有必需的类。我检查文件。一切似乎都还好。我有一个数组,我可以有 1 个以上的结果。 -
在我的代码中,我有一个 xml 要反序列化(我用来生成 xsd 的那个),我用以下代码反序列化它:
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; }
我得到的是一个只有一个元素的数组,但 xml 有两个元素(我已经在调试时检查过)。可能是什么问题?
更新
遵循 XML 和 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>
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>
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>
生成的类具有以下代码:
...
[System.Xml.Serialization.XmlElementAttribute("StoredProcedureResultSet0")]
public SELECT_CONFIGURATIONResponseStoredProcedureResultSet0[] StoredProcedureResultSet0
{
get
{
return this.storedProcedureResultSet0Field;
}
set
{
this.storedProcedureResultSet0Field = value;
}
}
...
好吧,XML 不会针对发布的架构进行验证:
错误: 命名空间中的元素"存储过程结果集0"http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo"具有无效的子元素命名空间中的"StoredProcedureResultSet0"http://schemas.microsoft.com/Sql/2008/05/ProceduresResultSets/dbo/SELECT_CONFIGURATION"。
错误:命名空间中的元素"SELECT_CONFIGURATIONResponse"http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo"具有无效的子元素"返回值"在命名空间"http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo"中。可能元素列表预期:"存储过程结果集0"在命名空间中"http://schemas.microsoft.com/Sql/2008/05/TypedProcedures/dbo"。
因此,您的 XML 或 XSD 需要更改。我会适当地更改first.xsd
:
<?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>
重新生成 xsd 类并对代码进行细微更改(集合在层次结构中向上移动),您就可以开始了。
问题是您的 XML 与您的 XSD 不匹配。 XSD 定义以下层次结构:
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
}
即,数组是类CONFIGURATIONResponse
的属性,使用方式如下:
var data = xml.LoadFromXML<SELECT_CONFIGURATIONResponse>();
for (int i = 0; i < data.StoredProcedureResultSet0.Length; i++)
Debug.WriteLine(data.StoredProcedureResultSet0[i].StoredProcedureResultSet0.FlowId);
但是,您的 XML 在 INNER 嵌套元素上具有数组,就好像类是这样定义的:
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
}
若要修复 XML,需要使其与 XSD 匹配,如下所示:
<?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>