C # Массив XmlElement добавляет еще один уровень вложенности - PullRequest
0 голосов
/ 09 июля 2019

У меня следующая ситуация:

  • 4 метода, которые возвращают XML
  • Необходимо создать один большой XML с этими 4 частями XML в массиве

Небольшой пример этого может быть следующим:

<garage>
    <owner>daniel</owner>
    <cars>
        <XmlElement>
            <plate>ABC123</plate>
        </XmlElement>
        <XmlElement>
            <plate>DSC563</plate>
        </XmlElement>
        <XmlElement>
            <plate>AIO789</plate>
        </XmlElement>
        <XmlElement>
            <plate>IUE692</plate>
        </XmlElement>
    </cars>
</garage>

У меня есть массив plate, и я хочу добавить его на car, который является System.Xml.XmlElement[]

Проблема в том, что я не могу найти способ избавиться от элемента XmlElement, обертывающего мои объекты, я просто хотел, чтобы он был таким:

<garage>
    <owner>
        <name>daniel</name>
    </owner>
    <cars>
        <plate>ABC123</plate>
        <plate>DSC563</plate>
        <plate>AIO789</plate>
        <plate>IUE692</plate>
    </cars>
</garage>

Я пытался поигратьс атрибутами XML, но не смог получить именно то, что я хотел.

Может кто-нибудь помочь мне?

вот рабочий код:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using Xunit;
using Xunit.Abstractions;

namespace TestsProjec.XML
{
    public class Tests
    {
        private readonly ITestOutputHelper _testOutputHelper;

        public Tests(ITestOutputHelper testOutputHelper)
        {
            _testOutputHelper = testOutputHelper;
        }

        [Fact]
        public void InjectingXml()
        {
            var serializer = new XmlSerializer(typeof(Garage));
            var cars = new List<XmlElement>();
            cars.Add(StringToXmlElement("<plate>ABC123</plate>"));
            cars.Add(StringToXmlElement("<plate>DSC563</plate>"));
            cars.Add(StringToXmlElement("<plate>AIO789</plate>"));
            cars.Add(StringToXmlElement("<plate>IUE692</plate>"));

            string fullXml;

            var entity = new Garage()
            {
                owner = "Daniel",
                cars = cars.ToArray()
            };

            using (MemoryStream ms = new MemoryStream())
            {
                using (XmlWriter tw = XmlWriter.Create(ms))
                {
                    serializer.Serialize(tw, entity);

                    try
                    {
                        byte[] tmp = new byte[ms.Length - 3];
                        ms.Position = 3; //to skip the UTF-8 preamble
                        ms.Read(tmp, 0, (int)ms.Length - 3);
                        fullXml = Encoding.UTF8.GetString(tmp);
                    }
                    catch
                    {
                        fullXml = null;
                    }
                }
            }

            _testOutputHelper.WriteLine(fullXml);
        }

        public XmlElement StringToXmlElement(string xml)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            return doc.DocumentElement;  
        }


    }

    public class Garage
    {
        public string owner { get; set; }
        public System.Xml.XmlElement[] cars { get; set; }
    }
}

Ответы [ 2 ]

1 голос
/ 09 июля 2019

Если вы используете XElement вместо XmlElement, вы можете получить желаемый результат с XmlAnyElement Атрибутом:

public class Garage
{
    public string owner { get; set; }
    [XmlAnyElement]
    public XElement[] cars { get; set; }
}

Ваш метод StringToXmlElement будет выглядеть так:

public XElement StringToXmlElement(string xml)
{
    return XElement.Parse(xml);
}
0 голосов
/ 09 июля 2019

Можно использовать XmlSerializer и иметь класс, представляющий ваш xml

class Program
{
    static void Main(string[] args)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Garage));
        var garage = new Garage
        {
            Owner = new Owner { Name = "Daniel" },
            Cars = new List<string>
            {
                "ABC123",
                "DSC563",
                "AIO789",
                "IUE692",
            }
        };

        serializer.Serialize(File.Create("file.xml"), garage);
    }
}

[Serializable]
public class Garage
{
    [XmlElement("Owner")]
    public Owner Owner;

    [XmlArrayItem("Plate")]
    public List<string> Cars;
}

[Serializable]
public class Owner
{
    [XmlElement("Name")]
    public string Name;
}
...