我被一个需要在InfoPath中创建应用程序的项目所诅咒,该应用程序使用了巨大的表单。为了从InfoPath XML访问数据,我选择使用XSD实用程序根据InfoPath生成的XML模式创建序列化的c#类。
由于InfoPath表单包含多个表,因此这些表在序列化类中实现为行类型的数组。当读入(反序列化)XML时,数组元素显然被分配和填充。
我无法弄清楚如何添加额外的数组元素。例如,如果XML在表中有两个条目,则该数组将分配两个元素。但我希望能够在阵列中添加其他元素。
我尝试使用Array.Resize方法没有太多运气。
这听起来很熟悉吗?
- 汤姆
答案 0 :(得分:3)
我会使用扩展方法(或部分类)来允许在XSD.exe创建的类中轻松地将项添加到数组中。由于XSD.exe生成数组而不是列表,因此向数组添加元素有点麻烦。如果使用扩展方法,则可以使类更易于使用。
下面的示例代码基于我使用以下xml创建的一组类:
<?xml version="1.0" encoding="utf-8" ?>
<Doc>
<Item Text="A" />
<Item Text="B" />
<Item Text="C" />
<Item Text="D" />
</Doc>
以下程序将上述XML反序列化为Doc
对象,并利用AddDocItem
扩展方法将项添加到Doc.Items
数组。 AddDocItem
使用Array.Resize
添加元素。
using System;
using System.IO;
using System.Xml.Serialization;
namespace TestConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var xmlSerialzer = new XmlSerializer(typeof(Doc));
var doc = xmlSerialzer.Deserialize(
new StreamReader(@"..\..\XmlFile1.xml")) as Doc;
if(doc == null) return;
doc.PrintDocItems();
Console.WriteLine();
//Add a couple new items
doc.AddDocItem(new DocItem { Text = "E" });
doc.AddDocItem(new DocItem { Text = "F" });
doc.PrintDocItems();
}
}
public static class DocExtensions
{
public static void AddDocItem(this Doc doc, DocItem item)
{
var items = doc.Items;
Array.Resize(ref items, items.Length + 1);
items[items.Length - 1] = item;
doc.Items = items;
}
public static void PrintDocItems(this Doc doc)
{
foreach (var item in doc.Items)
Console.WriteLine(item.Text);
}
}
}
如果您不是扩展方法的粉丝,您可以利用XSD.exe生成的类是部分类这一事实,并以这种方式扩展类。例如:
public partial class Doc
{
public void AddDocItem(DocItem item)
{
var items = Items;
Array.Resize(ref items, items.Length + 1);
items[items.Length - 1] = item;
Items = items;
}
public void PrintDocItems()
{
foreach (var item in Items)
Console.WriteLine(item.Text);
}
}
无论哪种方式都可以正常工作。
XSD.exe生成的代码如下所示:
namespace TestConsoleApplication1
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class Doc {
private DocItem[] itemsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Item", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public DocItem[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class DocItem {
private string textField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Text {
get {
return this.textField;
}
set {
this.textField = value;
}
}
}
}
希望有所帮助。