сериализация xml тегов в c# словарь - PullRequest
1 голос
/ 18 апреля 2020

У меня есть API, который возвращает xml в следующей форме

<root>
<sometag>somevalue</sometag>
<sometag>somevalue</sometag>
<Rights>
    <admin>true</admin>
    <admin_employees>true</admin_employees>
    <admin_inventory>true</admin_inventory>
    <admin_purchases>true</admin_purchases>
    <admin_shops>true</admin_shops>
    <admin_void_sale>true</admin_void_sale>
</Rights>
</root>

Я использую System. Xml .Serialization, и у меня возникают проблемы с сериализацией без прав раздела «Права» печатая всю вещь так, как она использовалась только один раз.

В идеале, я хотел бы, чтобы она сериализовалась в словарь с ключевым именем тега. Как бы я этого достиг? или есть другой метод, который будет работать лучше?

в надежде на использование, подобное if(Rights["admin"]) ...

Ответы [ 2 ]

0 голосов
/ 18 апреля 2020

Поскольку вы упомянули об использовании XmlSerializer для десериализации контента,

, чтобы придерживаться его, вот еще одно решение, использующее XmlSerializer.Deserialize (), чтобы помочь вам, если у вас уже есть класс для всего root объект, но не хотите вводить свойства для каждого флага в коллекции прав.

[XmlRoot("root")]
public class RootObject
{
    // . . . other properties
    // . . . if you have them
    // . . . and just don't put here anything
    // . . . if you don't need them
    public XmlElementDictionary<bool> Rights { get; set; }
}

Если полученный XML имеет точно такой же формат, как вы задали в своем вопросе, следующее проанализирует элементы прав в словаре. Реализуя IXmlSerializable, мы сообщаем системе сериализации, что хотим сами сериализовать / десериализовать этот тип.

Обратите внимание, что поддержка записи и схемы не реализована.

public class XmlElementDictionary<TValue> : Dictionary<string, TValue>, IXmlSerializable
{
    void IXmlSerializable.ReadXml(XmlReader reader)
    {
        string startElementName = reader.Name;
        while (reader.Read())
        {
            string keyName = reader.Name;
            if (keyName == startElementName) break;
            reader.Read(); // Read element value
            base.Add(keyName, (TValue)Convert.ChangeType(reader.Value, typeof(TValue)));
            reader.Read(); // Read end element

        }
    }

    System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() { throw new NotImplementedException(); }
    void IXmlSerializable.WriteXml(XmlWriter writer) { throw new NotImplementedException(); }
}

Обобщение * Реализация 1017 * делает это повторно используемым для других типов. Логика чтения c может быть улучшена для проверки любых атрибутов (теперь не удается, если есть атрибуты, но должна дать вам четкое представление о том, как читать только элемент и его внутренний текст)

Вот как это сделать используйте это:

static void Main(string[] args)
{
    RootObject rootObject = 
        (RootObject)new XmlSerializer
            (typeof(RootObject)).Deserialize(new StringReader(XML));

    if(rootObject.Rights["admin"])
    {
        . . . .
    }
}
0 голосов
/ 18 апреля 2020

См. Следующее:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            Dictionary<string, Boolean> dict = doc.Descendants("Rights").FirstOrDefault().Elements()
                .GroupBy(x => x.Name.LocalName, y => (Boolean)y)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...