Добавление строкового индексатора в XmlSerializer

У меня есть источник XML, который я не могу изменить, и я хочу десериализовать его с помощью XmlSerializer.

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

Я знаю, что могу использовать

public ClassName this[string index] 

но я не могу понять, где добавить это в мой класс.

Я хочу иметь возможность звонить

Object.Transaction["TransactionTypeName"] 

вместо

Object.Transaction[0]

Это урезанная версия класса.

public partial class Configuration
{
    private ConfigurationTransaction[] transactionsField;

    [System.Xml.Serialization.XmlArrayItemAttribute("Transaction", IsNullable = false)]
    public List<ConfigurationTransaction> Transactions
    {
        get
        {
            return this.transactionsField;
        }
        set
        {
            this.transactionsField = value;
        }
    }
}

public partial class ConfigurationTransaction
{
    private string typeField;

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string type
    {
        get
        {
            return this.typeField;
        }
        set
        {
            this.typeField = value;
        }
    }

}

2 ответа

Я был в состоянии добавить это в классе конфигурации.

public ConfigurationTransaction this[String index]
{
    get
    {
        foreach (var item in Transactions)
        {
            if (item.type.ToLower().Trim() == index.ToLower().Trim())
            {
                return item;
            }
        }
        return null;
    }
}    

И называть это как

Object["TransactionTypeName"] 

Я думаю, что именно это я и сделал, в итоге я вручную импортировал все данные в базу данных SQL и создал класс Entity Framework для доступа к нему и ограничил решение XML.

Упрощенный пример кода ваших классов с индексатором. Пока нам нужно сохранить значение для доступа к индексатору, придется создать дополнительный класс.

public class Configuration
{
    public ConfigurationTransaction this[string transactionName]
    {
        get
        {
            return Transactions.First(tran => tran.TransactionName == transactionName).ConfigurationTransaction;
        }
        set
        {
            int index = Transactions.FindIndex(tran => tran.TransactionName == transactionName);
            if (index >= 0)
                Transactions[index] = new PairHelper { TransactionName = transactionName, ConfigurationTransaction = value };
            else
                Transactions.Add(new PairHelper { TransactionName = transactionName, ConfigurationTransaction = value });
        }
    }
    [EditorBrowsable(EditorBrowsableState.Never)]
    public List<PairHelper> Transactions { get; set; }
}

public class ConfigurationTransaction
{
    [XmlAttribute()]
    public string Type { get; set; }
}

public class PairHelper
{
    public string TransactionName { get; set; }
    public ConfigurationTransaction ConfigurationTransaction { get; set; }
}

Это работает:

Configuration conf = new Configuration();
conf.Transactions = new List<PairHelper>();
conf["fooTran"] = new ConfigurationTransaction { Type = "foo" };
conf["barTran"] = new ConfigurationTransaction { Type = "bar" };

var xs = new XmlSerializer(typeof(Configuration));
using (var fs = new FileStream("test.txt", FileMode.Create))
{
    xs.Serialize(fs, conf);
}

Configuration conf2;
using (var fs = new FileStream("test.txt", FileMode.Open))
{
    conf2 = (Configuration)xs.Deserialize(fs);
}

foreach (var tran in conf2.Transactions)
    Console.WriteLine(tran.TransactionName + " : " + tran.ConfigurationTransaction);
Console.WriteLine(conf2["fooTran"].Type);
Console.WriteLine(conf2["barTran"].Type);

XML будет выглядеть так:

<?xml version="1.0"?>
<Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Transactions>
    <PairHelper>
      <TransactionName>fooTran</TransactionName>
      <ConfigurationTransaction Type="foo" />
    </PairHelper>
    <PairHelper>
      <TransactionName>barTran</TransactionName>
      <ConfigurationTransaction Type="bar" />
    </PairHelper>
  </Transactions>
</Configuration>
Другие вопросы по тегам