Как я могу управлять частью XML-сериализации <? Xml?> С помощью .NET?
Я использую этот метод для сериализации моего объекта:
public static string XmlSerialize(object o)
{
var stringWriter = new StringWriter();
var xmlSerializer = new XmlSerializer(o.GetType());
xmlSerializer.Serialize(stringWriter, o);
string xml = stringWriter.ToString();
stringWriter.Close();
return xml;
}
Это делает XML, который начинается следующим образом:
<?xml version="1.0" encoding="utf-16"?>
<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
Но я хочу, чтобы это выглядело так:
<?xml version = "1.0" encoding="Windows-1252" standalone="yes"?>
<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
Итак, как мне изменить кодировку на Windows-1252 и установить standalone = yes?
Кроме того, как мне получить объект, чтобы исключить значение xmlns?
Я видел пару подобных вопросов, например этот, но я надеялся, что это может быть проще для меня, может быть, где-то установить некоторые атрибуты?
Обновление 2: посмотрев на ответ Джона и комментарии, и подумав об этом больше, я решил просто сделать второй метод. Я не думаю, что создание этого дурацкого пользовательского xml только для третьей стороны в одно время должно быть названо чем-то общим как "XmlSerialize" в первую очередь.
Итак, я создал второй метод, который принимает XML-документ и, во-первых, удаляет один элемент пространства имен следующим образом:
xElement.Attributes().Where(a => a.IsNamespaceDeclaration && a.Value == "http://www.w3.org/2001/XMLSchema").Remove();
тогда он записывает его в XML с кодом Джона. Наконец, он возвращает этот xml, следуя следующему выводу:
new XDeclaration("1.0", "Windows-1252", "yes").ToString()
И это некрасиво, но это дает мне именно то, что мне нужно для этой третьей стороны, чтобы понять мой XML.
Ответы
Ответ 1
Попробуйте следующее:
public static string XmlSerialize(object o)
{
using (var stringWriter = new StringWriter())
{
var settings = new XmlWriterSettings
{
Encoding = Encoding.GetEncoding(1252),
OmitXmlDeclaration = true
};
using (var writer = XmlWriter.Create(stringWriter, settings))
{
var xmlSerializer = new XmlSerializer(o.GetType());
xmlSerializer.Serialize(writer, o);
}
return stringWriter.ToString();
}
}
Это не избавится от пространства имен xsd:, но почему, почему вы хотите?
Обновление: Кажется, что всякий раз, когда вы используете StringWriter
, вы получаете UTF-16, даже если вы используете XmlWriter
поверх него с набором кодировок. Следующим шагом будет запись в MemoryStream
. Но это ставит вопрос о том, почему вы хотите вернуть строку. Например, если вы собираетесь просто развернуться и вывести строку в поток, то мы должны напрямую выводить этот поток. То же самое для TextWriter
.
Ответ 2
Вместо StringWriter вы можете использовать XmlTextWriter. Вот выдержка из моего кода с вашим набором кодировок.
XmlTextWriter textWriter = new XmlTextWriter(stream, Encoding.GetEncoding(1252));
textWriter.Namespaces = false;
Ответ 3
FWIW, я получил кодировку для работы с помощью XmlWriter с XMLWriterSettings. Вот пример:
...
// My object type was from a class generated by xsd.
XmlSerializer xms = new XmlSerializer(typeof(SomeType));
SomeType objSt;
using(FileStream fs = new FileStream("C:\SomeFile.xml", FileMode.Open, FileAccess.Read))
{
using(XmlReader xr = XmlReader.Create(fs)) // Supposed to preserve encoding.
{
objSt = (SomeType)xms.Deserialize(xr);
}
}
...
... // Do some stuff, change some attribute values.
...
XmlWriterSettings xsw= new XmlWriterSettings();
xsw.Indent= true;
xsw.NewLineOnAttributes= true;
xsw.Encoding = Encoding.GetEncoding(1252);
using(XmlWriter xwXsw = XmlWriter.Create("C:\SomeFile_Changed.xml",xsw))
{
xms.Serialize(xwXsw, objSt);
}
...
... // Finish up and get out.
...
По какой-то причине я смог заставить все это работать, просто используя объект XmlSerializer и сериализуя его с помощью TextWriter, поскольку в соответствии с MS help для XmlSerializer.Deserialize(XmlReader) "XmlReader автоматически обнаруживает и использует указанную кодировку по XML-документу". Затем я начал играть с XmlWriterSettings и сломал что-то....