C#使用重复标签反序列化XML [英] C# Deserializing an XML with repeating tags
问题描述
我有一个输入XML字符串,该字符串带有重复的< row>
标签,我试图将它们反序列化为一个对象,但是除最后一行之外的所有行都被忽略了。任何帮助,将不胜感激。
I have an input XML string with repeating <row>
tags that I'm trying to deserialize into an object, but all the rows except the last one get ignored. Any help would be appreciated.
例如,反序列化之后,我得到的对象是:
As an example, after the deserialization, the object I get is:
object.command[0].userTable =
{OCI.OCITable}
colHeading: {string[3]}
colHeadingField: {string[3]}
row: {string[3]}
rowField: {string[3]}
这是错误的,因为此对象中只有一行,但是在这样的输入XML字符串中应该有4个< row>
:
This is wrong, because there is only one row in this object, but there should be 4 <row>
in the input XML string like this:
<?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#类$ c $
OCITable
类的c>是这样的:
And the C# class automatically generated by xsd.exe
for the OCITable
class is this:
[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>
元素是一个2d锯齿状数组:存在一个外部重复的< row>
元素集,其中包含一个内部重复的< col>元素。
元素,每个元素都有一个字符串值。但是在您的 OCITable
类中,您已将其建模为一维字符串数组:
The main problem is that, in your XML, the <row>
and <col>
elements are a 2d jagged array: there is an outer, repeating set of <row>
elements containing an inner, repeating set of <col>
elements, each of which has a string value. But in your OCITable
class you have modeled this as a 1d array of strings:
public string[] row { get; set; }
这仅允许一个外部< ; row>
元素。如果在解析时遇到多个< row>
元素,则 XmlSerializer
将用后面的值覆盖以前的值-
This only allows for one outer <row>
element. If multiple <row>
elements are encountered while parsing, XmlSerializer
will overwrite the earlier values with the later - which is exactly what you are seeing.
为了捕获行和列元素的嵌套层次结构,您需要执行以下操作:
In order to capture the nested hierarchy of row and column elements, you would instead need to do something like:
public string[][] row { get; set; }
但是,如果这样做,则会遇到C# xml序列化删除锯齿状的数组元素名称,即 XmlSerializer
将始终使用额外的外部容器元素序列化2d锯齿状数组,例如:
However, if you do, you will encounter the problem described in C# xml serialization remove jagged array element name, namely that XmlSerializer
will always serialize a 2d jagged array with an extra outer container element, like so:
<row>
<col>
<string>a</string>
</col>
<col>
<string>b</string>
</col>
</row>
因此这也不起作用。
相反,您需要使 row
成员成为一个简单的中间类数组,其中包含一维字符串数组,例如:
Instead, you will need to make your row
member a simple array of intermediate classes which contain a 1d array of strings, like so:
[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; }
}
两者均<< c $ c>行和 col
数组标记为 [XmlElement]
表示应将它们序列化为重复的元素序列,而无需外部容器元素。
Both the row
and col
arrays are marked with [XmlElement]
to indicate they should be serialized as a repeating sequence of elements without an outer container element.
使用上面定义的类,您将可以反序列化< userTable>
元素。样本小提琴。
With the classes defined above you will be able to deserialize your <userTable>
element. Sample fiddle.
这篇关于C#使用重复标签反序列化XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!