Десериализовать один тег XML в отдельные свойства с помощью C# - PullRequest
0 голосов
/ 11 марта 2020

Рассмотрим следующее упрощенное XML. Я получаю его от службы и не имею никакого влияния на его структуру. Он содержит 3 тега, которые определяются их порядком, то есть первый <string> всегда ссылается на одно и то же свойство .

<?xml version="1.0" encoding="UTF-8"?>
<result>
   <entry>
      <string>foo</string>
      <int>42</int>
      <string>bar</string>
   </entry>
   <entry>
      <string>baz</string>
      <int>1234</int>
      <string>foobar</string>
   </entry>
</result>

Я бы хотел десериализовать <entry> элементы в класс с отдельными свойствами, например

public class ResultEntry {
  // this property equals to the 1st-occuring <string> element in the XML
  public String PropA { get; set; }
  // this property equals to the 2nd-occuring <string> element in the XML
  public String PropB { get; set; }
  // this property equals to the <int> element in the XML
  public Int32  PropC { get; set; }
}

Есть ли способ десериализации двух <string> элементов в два разных свойства? Я не могу просто добавить аннотацию [XmlElement(ElementName="string")] к ним обоим, так как это приводит к InvalidOperationException.

Одним из способов может быть добавление свойства типа

[XmlElement(ElementName="string")]
public List<string> StringVals {get; set;}

и вручную переместить значения позже, но мне это кажется слишком хаки .

1 Ответ

0 голосов
/ 11 марта 2020

Используйте следующее:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication161
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(Result));
            Result result = (Result)serializer.Deserialize(reader);
        }
    }
    [XmlRoot("result")]
    public class Result
    {
        [XmlElement("entry")]
        public List<ResultEntry> entries { get; set; }
    }
    public class ResultEntry
    {
        [XmlElement("string")]
        public List<String> PropA { get; set; }
        [XmlElement("int")]
        public int PropB { get; set; }
    }
}

Вы можете сделать что-то вроде ниже, что я не рекомендую

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication161
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(Result));
            Result result = (Result)serializer.Deserialize(reader);
        }
    }
    [XmlRoot("result")]
    public class Result
    {
        [XmlElement("entry")]
        public List<ResultEntry> entries { get; set; }
    }
    public class ResultEntry
    {
        private string PropA { get; set; }
        private string PropB { get; set; }

        [XmlElement("string")]
        public List<String> Properties {
            get { return new List<string> { PropA, PropB};}
            set { PropA = value[0]; PropB = value[1]; }
        }
        [XmlElement("int")]
        public int PropC { get; set; }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...