Сериализация элемента XML и элемента массива XML с тем же именем

Я хочу сериализовать XML-документы из сторонней службы, которые представлены в любом из двух форматов (я добавил отступы для облегчения чтения):

1.

<STADMessage>Invalid Request, no content provided!</STADMessage>

2.

<STADMessage>
    <Message>Invalid Request, see log for detail using reference: ASDFL210359872305982035</Message>
</STADMessage>

Прямо сейчас я взламываю XML-документ, прежде чем он будет сериализован с помощью следующего кода

xmlDocument.Replace("<STADMessage><Message>", "<STADMessages><Message>")
           .Replace("</Message></STADMessage>", "</Message></STADMessages>");

Фрагмент сериализованного класса

[XmlElement(ElementName = "STADMessage", IsNullable = true)]
public string STADMessage { get; set; }

[XmlArray(ElementName = "STADMessages", IsNullable = true)]
[XmlArrayItem("Message", typeof(string))]
public List<string> STADMessages { get; set; }

Есть способ чище?

Ух, это так некрасиво с их стороны делать это со своей стороны. Вы должны отправить запрос их команде разработчиков и научить их, что такое стандартизация.

ugh StackExchange 30.10.2018 01:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
81
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы жестяная банка заставите их изменить ее на правильную структуру, как рекомендует @FrankerZ, это было бы идеально. Если не можете, надеюсь, это поможет.

Вы можете учесть это изменение с помощью настраиваемого объекта сериализации, который десериализует по-разному зависит от типа входящего узла.

Измените тип свойства STADMessage на пользовательский тип (я назову его STADMessage, черт возьми):

[XmlElement(ElementName = "STADMessage", IsNullable = true)]
public STADMessage STADMessage { get; set; }

А вот и класс STADMessage:

public class MySTADMessage : IXmlSerializable
{
    public string Message { get; set; }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        // IsNullable = true is ignored, apparently.  You won't get an actual
        // null for properties deserialized this way because the serializer
        // already created an instance of this class.
        if (reader.GetAttribute("nil", XmlSchema.InstanceNamespace) == "true")
            return;

        reader.ReadStartElement();

        while (reader.NodeType == XmlNodeType.Whitespace)
            reader.Read();

        if (reader.NodeType == XmlNodeType.Text)
        {
            Message = reader.ReadContentAsString();
        }
        else if (reader.NodeType == XmlNodeType.Element)
        {
            if (reader.Name != "Message")
                throw new Exception("Unexpected element name.");

            reader.ReadStartElement();
            if (reader.NodeType == XmlNodeType.Text)
            {
                Message = reader.ReadContentAsString();
            }
            else
            {
                throw new Exception("Unexpected node type.");
            }
            reader.ReadEndElement();
        }
        else
        {
            throw new Exception("Unexpected node type.");
        }
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        // Not having the extra Message element is simpler.
        writer.WriteString(Message);
    }
}

Это грубо, это не довольно правильно реализует IXmlSerializable по сегодняшним стандартам, и, вероятно, не учитывает все, но это должно помочь вам начать.

Другие вопросы по теме

Гибридный поток Identity Server (OpenID Connect): требуется, чтобы пользователь оставался в системе в течение 5 лет с использованием токенов обновления
Используйте регулярное выражение для извлечения определенного предложения select из оператора SQL с помощью .Net
.net ORM, который позволит мне расширить мой код, не изменяя его (принцип открытого закрытия)
Как определить интеллектуальный xPath на основе уникального значения, содержащегося в неуникальных тегах XML, для использования с методом XmlNode.SelectNodes () в C#?
Проверить текущий узел с помощью XPath
Преобразовать System.Drawing.Color в int?
.NET Как установить имя потока для процесса, который я запускаю программно
Как избежать исключений с нулевой ссылкой при итерации через IEnumerable datarow?
Перенаправить на пользовательскую страницу в случае ошибки без использования Response.Redirect (url) в .net?
Получить значение Entry в формах ListView Xamarin