Как мне контролировать <? Xml?> Часть сериализации xml с .NET? - PullRequest
13 голосов
/ 16 сентября 2009

Я использую этот метод для сериализации моего объекта:

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.

Ответы [ 3 ]

25 голосов
/ 16 сентября 2009

Попробуйте это:

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 голосов
/ 16 сентября 2009

Вы можете использовать XmlTextWriter вместо StringWriter. Вот выдержка из моего кода с вашим набором кодировок.

XmlTextWriter textWriter = new XmlTextWriter(stream, Encoding.GetEncoding(1252));
textWriter.Namespaces = false;
0 голосов
/ 12 августа 2011

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 для XmlSerializer.Deserialize (XmlReader) «XmlReader автоматически обнаруживает и использует указанную кодировку по документу XML. " Затем я начал играть с XmlWriterSettings и что-то сломал ....

...