Пространство имен сериализации XML для дочерних и родительских элементов

Всем добрый день,

У меня возникают проблемы с правильным добавлением пространств имен в мой XML. И родительский, и дочерний элементы имеют собственные пространства имен. При реструктуризации кода я получил смешанные результаты. Мой пример кода ниже:

using System;
using System.IO;
using System.Xml.Serialization;

namespace XmlSerializationExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var grandchild = new grandchild_element { Value = "randomResults" };
            var child = new child_element { grandchildElement = grandchild };
            var parent = new parent_element { childElement = child };

            var serializer = new XmlSerializer(typeof(parent_element), "www.testing.com");
            var namespaces = new XmlSerializerNamespaces(new[]
            {
                new XmlQualifiedName("xsi", "http://www.w3.org/2001/XMLSchema-instance")
            });
            var settings = new XmlWriterSettings
            {
                OmitXmlDeclaration = true,
                Indent = true,
                Encoding = System.Text.Encoding.UTF8
            };

            string xmlOutPut = @"C:\Users\[user]\Desktop\xml_test_file_" + DateTime.Now.ToString("HHmmss") + ".xml";

            using (var fileStream = new FileStream(xmlOutPut, FileMode.Create))
            using (var xmlWriter = XmlWriter.Create(fileStream, settings))
            {
                xmlWriter.WriteStartElement("parentElement", "www.testing.com");

                serializer.Serialize(xmlWriter, parent, namespaces);

                xmlWriter.WriteEndElement();
            }
        }
    }

    [XmlRoot(ElementName = "parentElement", Namespace = "www.testing.com")]
    public class parent_element
    {
        public child_element childElement { get; set; }
    }

    public class child_element
    {
        [XmlElement(ElementName = "grandchildElement")]
        public grandchild_element grandchildElement { get; set; }

        [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string xsi = "http://www.w3.org/2001/XMLSchema-instance";

        [XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
        public string type = "text_type";
    }

    public class grandchild_element
    {
        [XmlText]
        public string Value { get; set; }
    }
}

Мои результаты были

<parentElement xmlns = "www.testing.com">

  <parentElement xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance">

    <childElement xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:type = "text_type">

      <grandchildElement>randomResults</grandchildElement>

    </childElement>

  </parentElement>

</parentElement>

Результат, который я ищу, без второго parentElement. Что-то похожее на то, что ниже

<parentElement xmlns = "www.testing.com">

    <childElement xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:type = "text_type">

      <grandchildElement>randomResults</grandchildElement>

    </childElement>

</parentElement>

Любая помощь будет здорово. Я знаю, что что-то просматриваю, но не знаю что. Заранее огромное спасибо

new XmlSerializer(typeof(child_element) наверное
Charlieface 25.04.2023 01:36

Только что попытался изменить var serializer = new XmlSerializer(typeof(parent_element), "www.testing.com") на var serializer = new XmlSerializer(typeof(child_element), "www.testing.com")К сожалению, это не сработало. Все еще тестирую его, и я думаю, что это может быть что-то с var namespaces или WriteStartElement

learning 25.04.2023 02:08
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  • Удалите ниже 2 обращения к xmlWriter.
xmlWriter.WriteStartElement("parentElement", "www.testing.com");

xmlWriter.WriteEndElement();
  • Вам не нужна настройка XmlSerializerNamespaces.

  • Удалите ниже свойство xsi из класса child_element.

[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string xsi = "http://www.w3.org/2001/XMLSchema-instance";
  • В целях десериализации добавьте атрибут [XmlType("text_type")] к классу child_element.

Классы вашей модели будут выглядеть так, как показано ниже.

[XmlRoot(ElementName = "parentElement", Namespace = "www.testing.com")]
public class parent_element
{
    public child_element childElement { get; set; }
}

[XmlType("text_type")]
public class child_element
{
    [XmlElement(ElementName = "grandchildElement")]
    public grandchild_element grandchildElement { get; set; }

    [XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
    public string type = "text_type";
}

public class grandchild_element
{
    [XmlText]
    public string Value { get; set; }
}

В следующем коде показано, как выполнить сериализацию.

var grandchild = new grandchild_element { Value = "randomResults" };
var child = new child_element { grandchildElement = grandchild };
var parent = new parent_element { childElement = child };

var serializer = new XmlSerializer(typeof(parent_element));
var settings = new XmlWriterSettings
{
    OmitXmlDeclaration = true,
    Indent = true,
    Encoding = System.Text.Encoding.UTF8,
};

string xmlOutPut = @"C:\Users\[user]\Desktop\xml_test_file_" + DateTime.Now.ToString("HHmmss") + ".xml";

using (var fileStream = new FileStream(xmlOutPut, FileMode.Create))
using (var xmlWriter = XmlWriter.Create(fileStream, settings))
{
    serializer.Serialize(xmlWriter, parent);
}

Это приведет к следующему xml.

<parentElement 
    xmlns = "www.testing.com"
    xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd = "http://www.w3.org/2001/XMLSchema">
  <childElement xsi:type = "text_type">
    <grandchildElement>randomResults</grandchildElement>
  </childElement>
</parentElement>

Ваш xml по-прежнему недействителен

Serge 25.04.2023 11:55

его нельзя десериализовать в класс С#. Я удалю отрицательный голос, как только вы исправите xml.Compiller выдает ошибку <parentElement xmlns='www.testing.com'> не ожидалось.

Serge 25.04.2023 12:10

@Serge При десериализации действительно произошла ошибка The specified type was not recognized: name='text_type', namespace='www.testing.. Теперь десериализация завершается успешно путем добавления [XmlType("text_type")] к классу child_element. Я обновил свой пост. Спасибо, что заметили.

pfx 25.04.2023 13:15

Я проголосовал за ваш ответ, но он все еще не совсем действителен. Я не знаю XML, так как это древняя технология, но я использую Visual Studio для проверки. Я копирую текст xml, и если он полностью действителен, я вижу опцию редактора VS «Вставить XML как класс», но в этом случае я не вижу эту опцию

Serge 25.04.2023 13:51

@Serge Привет, учитывая ваше правильное предыдущее замечание, я дал приведенный выше код для полной сериализации и десериализации туда и обратно и больше не сталкиваюсь с исключениями.

pfx 25.04.2023 14:23

@pfx Спасибо за вашу помощь, я думаю, что приближаюсь к ответу. Я просто запустил его со своей стороны с предоставленным вами исправленным кодом, и я смог получить те же результаты, что и вы. К сожалению, результаты, которые я ищу, имеют xmlns:xsi на дочернем элементе и только xmlns = testing на родительском элементе.

learning 25.04.2023 16:07

@learning Нет никакой дополнительной ценности в том, чтобы xmlns:xsi находиться на другом уровне. По соглашению вы найдете их чаще всего, если не всегда, в корневом элементе. Я бы не стал прилагать к этому слишком много усилий.

pfx 25.04.2023 16:19

@pfx Спасибо за вашу помощь, я думаю, что начинаю понимать это намного лучше. Отметив свой как ответ. Еще раз большое спасибо

learning 25.04.2023 16:40

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