我有一个重复的输入 XML 字符串 <row>
我试图将其反序列化为对象的标签,但除最后一行之外的所有行都被忽略。任何帮助,将不胜感激。
举个例子,反序列化后,我得到的对象是:
object.command[0].userTable =
{OCI.OCITable}
colHeading: {string[3]}
colHeadingField: {string[3]}
row: {string[3]}
rowField: {string[3]}
这是错误的,因为这个对象中只有一行,但应该有 4 <row>
在输入 XML 字符串中,如下所示:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<BroadsoftDocument protocol="OCI" xmlns="C" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<sessionId xmlns="">feajiofefeaij</sessionId>
<command echo="" xsi:type="UserGetListInServiceProviderResponse" xmlns="">
<userTable>
<colHeading>User Id</colHeading>
<colHeading>Group Id</colHeading>
<colHeading>Name</colHeading>
<row>
<col>1</col>
<col>A</col>
<col>Smith</col>
</row>
<row>
<col>2</col>
<col>A</col>
<col>John</col>
</row>
<row>
<col>3</col>
<col>B</col>
<col>James</col>
</row>
<row>
<col>4</col>
<col>B</col>
<col>Lisa</col>
</row>
</userTable>
</command>
</BroadsoftDocument>
我进行反序列化的方式是:
MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(responseString));
XmlSerializer ser = new XmlSerializer(typeof(OCIMessage));
OCIMessage response = (OCIMessage)ser.Deserialize(memStream);
以及xsd.exe
自动生成的C#类对于OCITable
类是这样的:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "C")]
public partial class OCITable
{
private string[] colHeadingField;
private string[] rowField;
[System.Xml.Serialization.XmlElementAttribute("colHeading", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string[] colHeading
{
get
{
return this.colHeadingField;
}
set
{
this.colHeadingField = value;
}
}
[System.Xml.Serialization.XmlArrayAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
[System.Xml.Serialization.XmlArrayItemAttribute("col", typeof(string), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)]
public string[] row
{
get
{
return this.rowField;
}
set
{
this.rowField = value;
}
}
}
最佳答案
主要问题是,在 XML 中, <row>
和 <col>
元素是一个二维锯齿状数组:有一个外部重复的 <row>
元素集,其中包含一个内部重复的 <col>
元素集,每个元素都有一个字符串值(value)。但在您的 OCITable
类中,您已将其建模为一维字符串数组:
public string[] row { get; set; }
这只允许一个外部<row>
元素。如果解析时遇到多个 <row>
元素,XmlSerializer
将用后面的值覆盖前面的值 - 这正是您所看到的。
为了捕获行和列元素的嵌套层次结构,您需要执行以下操作:
public string[][] row { get; set; }
但是,如果这样做,您将遇到 C# xml serialization remove jagged array element name 中描述的问题,即 XmlSerializer
总是会序列化带有额外外部容器元素的二维交错数组,如下所示:
<row>
<col>
<string>a</string>
</col>
<col>
<string>b</string>
</col>
</row>
因此这也行不通。
相反,您需要使 row
成员成为一个简单的中间类数组,其中包含一维字符串数组,如下所示:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "C")]
public partial class OCITable
{
private string[] colHeadingField;
[System.Xml.Serialization.XmlElementAttribute("colHeading", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string[] colHeading
{
get
{
return this.colHeadingField;
}
set
{
this.colHeadingField = value;
}
}
[System.Xml.Serialization.XmlElement(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public OCITableRow [] row { get; set; }
}
public class OCITableRow
{
[System.Xml.Serialization.XmlElementAttribute("col", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)]
public string[] col { get; set; }
}
row
和 col
数组都标有 [XmlElement]
,以指示它们应被序列化为不带外部容器元素的重复元素序列。
使用上面定义的类,您将能够反序列化 <userTable>
元素。样本fiddle。
关于C# 反序列化带有重复标签的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39197889/