How to put an encoding attribute to xml other that utf-16 with XmlWriter?

前端 未结 5 1035
花落未央
花落未央 2020-12-01 10:33

I\'ve got a function creating some XmlDocument:

public string CreateOutputXmlString(ICollection fields)
{
    XmlWriterSettings settings = new X         


        
5条回答
  •  旧巷少年郎
    2020-12-01 10:48

    Just some extra explanations to why this is so.

    Strings are sequences of characters, not bytes. Strings, per se, are not "encoded", because they are using characters, which are stored as Unicode codepoints. Encoding DOES NOT MAKE SENSE at String level.

    An encoding is a mapping from a sequence of codepoints (characters) to a sequence of bytes (for storage on byte-based systems like filesystems or memory). The framework does not let you specify encodings, unless there is a compelling reason to, like to make 16-bit codepoints fit on byte-based storage.

    So when you're trying to write your XML into a StringBuilder, you're actually building an XML sequence of characters and writing them as a sequence of characters, so no encoding is performed. Therefore, no Encoding field.

    If you want to use an encoding, the XmlWriter has to write to a Stream.

    About the solution that you found with the MemoryStream, no offense intended, but it's just flapping around arms and moving hot air. You're encoding your codepoints with 'windows-1252', and then parsing it back to codepoints. The only change that may occur is that characters not defined in windows-1252 get converted to a '?' character in the process.

    To me, the right solution might be the following one. Depending on what your function is used for, you could pass a Stream as a parameter to your function, so that the caller decides whether it should be written to memory or to a file. So it would be written like this:

    
            public static void WriteFieldsAsXmlDocument(ICollection fields, Stream outStream)
            {
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent = true;
                settings.Encoding = Encoding.GetEncoding("windows-1250");
    
                using(XmlWriter writer = XmlWriter.Create(outStream, settings)) {
                    writer.WriteStartDocument();
                    writer.WriteStartElement("data");
                    foreach (Field field in fields)
                    {
                        writer.WriteStartElement("item");
                        writer.WriteAttributeString("name", field.Id);
                        writer.WriteAttributeString("value", field.Value);
                        writer.WriteEndElement();
                    }
                    writer.WriteEndElement();
                }
            }
    

提交回复
热议问题