Как добавить элементы в массив в сгенерированном сериализованном классе ac # XSD? - PullRequest
2 голосов
/ 12 августа 2011

Я был проклят с проектом, требующим создания приложения в InfoPath, которое использует гигантские формы.Чтобы получить доступ к данным из XML-файла InfoPath, я решил использовать утилиту XSD для создания сериализованного класса c # на основе сгенерированной XML-схемы InfoPath.

Поскольку форма InfoPath содержит несколько таблиц, таблицыреализован в сериализованном классе как массивы типа строки.Когда XML читается в (десериализованных) элементах массива, очевидно, выделяются и заполняются.

Я не могу понять, как добавить дополнительные элементы массива.Например, если XML имеет две записи в таблице, массив будет иметь два выделенных элемента.Но я хотел бы иметь возможность добавлять дополнительные элементы в массив.

Я попытался использовать метод Array.Resize без особой удачи.

Этот звук всем знаком?

-Tom

1 Ответ

3 голосов
/ 12 августа 2011

Я бы использовал методы расширения (или частичные классы), чтобы можно было легко добавлять элементы в массивы в классах, созданных 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;
            }
        }
    }
}

Надеюсь, что это поможет.

...