Всем добрый день,
У меня возникают проблемы с правильным добавлением пространств имен в мой 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>
Любая помощь будет здорово. Я знаю, что что-то просматриваю, но не знаю что. Заранее огромное спасибо
Только что попытался изменить var serializer = new XmlSerializer(typeof(parent_element), "www.testing.com") на var serializer = new XmlSerializer(typeof(child_element), "www.testing.com")К сожалению, это не сработало. Все еще тестирую его, и я думаю, что это может быть что-то с var namespaces или WriteStartElement





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 по-прежнему недействителен
его нельзя десериализовать в класс С#. Я удалю отрицательный голос, как только вы исправите xml.Compiller выдает ошибку <parentElement xmlns='www.testing.com'> не ожидалось.
@Serge При десериализации действительно произошла ошибка The specified type was not recognized: name='text_type', namespace='www.testing.. Теперь десериализация завершается успешно путем добавления [XmlType("text_type")] к классу child_element. Я обновил свой пост. Спасибо, что заметили.
Я проголосовал за ваш ответ, но он все еще не совсем действителен. Я не знаю XML, так как это древняя технология, но я использую Visual Studio для проверки. Я копирую текст xml, и если он полностью действителен, я вижу опцию редактора VS «Вставить XML как класс», но в этом случае я не вижу эту опцию
@Serge Привет, учитывая ваше правильное предыдущее замечание, я дал приведенный выше код для полной сериализации и десериализации туда и обратно и больше не сталкиваюсь с исключениями.
@pfx Спасибо за вашу помощь, я думаю, что приближаюсь к ответу. Я просто запустил его со своей стороны с предоставленным вами исправленным кодом, и я смог получить те же результаты, что и вы. К сожалению, результаты, которые я ищу, имеют xmlns:xsi на дочернем элементе и только xmlns = testing на родительском элементе.
@learning Нет никакой дополнительной ценности в том, чтобы xmlns:xsi находиться на другом уровне. По соглашению вы найдете их чаще всего, если не всегда, в корневом элементе. Я бы не стал прилагать к этому слишком много усилий.
@pfx Спасибо за вашу помощь, я думаю, что начинаю понимать это намного лучше. Отметив свой как ответ. Еще раз большое спасибо
new XmlSerializer(typeof(child_element)наверное