How do I control the <?xml ?> part of xml serialization with .NET?

好久不见. 提交于 2019-12-29 05:56:25

问题


I am using this method to serialize my object:

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;
}

It makes XML that starts like this:

<?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">

But I want it to look like this:

<?xml version = "1.0" encoding="Windows-1252" standalone="yes"?>
<MyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

So, how do I change the encoding to Windows-1252 and set standalone = yes? Additionally, how to I get the object to exclude the xmlns value?

I've seen a couple similar questions, like this one, but I was hoping it might be simpler for me, maybe by setting some attributes somewhere?

Update 2: After looking at John's answer and comments, and thinking about this more, I decided to just make a second method. I don't think that creating this wacky custom xml just for a 3rd party on one occasion should be called something as generic as "XmlSerialize" in the first place.

So, I created a second method that takes an XML document and first, removes the one namespace element like this:

xElement.Attributes().Where(a => a.IsNamespaceDeclaration && a.Value == "http://www.w3.org/2001/XMLSchema").Remove();

then, it it writes it to XML with John's code. Finally it returns that xml, following the output from this:

new XDeclaration("1.0", "Windows-1252", "yes").ToString()

And that's ugly, but it gets me exactly what I need for this 3rd party to understand my XML.


回答1:


Try this:

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();
    }
}

This won't get rid of the xsd: namespace, but then, why do you want to?


Update: It seems that whenever you use a StringWriter, you get UTF-16, even if you use an XmlWriter on top of it with encoding set. Next step would be to write out to a MemoryStream. But that raises the question of why you want to return a string. For instance, if you're going to just turn around and output the string to a stream, then we should output directly to this stream. Same for a TextWriter.




回答2:


You can use an XmlTextWriter instead of a StringWriter. Here is an extract from some of my code with your encoding set.

XmlTextWriter textWriter = new XmlTextWriter(stream, Encoding.GetEncoding(1252));
textWriter.Namespaces = false;



回答3:


FWIW, I got the encoding to work by using an XmlWriter with XMLWriterSettings. Here is a sample:

...  
// 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.
...  

For some reason, I was able to get it all to work once just using the XmlSerializer object and serializing with a TextWriter, since according to MS help for XmlSerializer.Deserialize(XmlReader) "The XmlReader automatically detects and uses the encoding specified by the XML document." Then I started playing with the XmlWriterSettings and broke something....



来源:https://stackoverflow.com/questions/1429593/how-do-i-control-the-xml-part-of-xml-serialization-with-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!