使用特殊字符反序列化 XML 的快速方法

Posted

技术标签:

【中文标题】使用特殊字符反序列化 XML 的快速方法【英文标题】:fast way to deserialize XML with special characters 【发布时间】:2011-06-21 10:55:55 【问题描述】:

我正在寻找反序列化 xml 的快速方法,其中包含特殊字符,例如 ö。

我使用的是 XMLReader,但它无法反序列化此类字符。

有什么建议吗?

编辑:我正在使用 C#。 代码如下:

XElement element =.. //has the xml
XmlSerializer serializer =   new XmlSerializer(typeof(MyType));
XmlReader reader = element.CreateReader();
Object o= serializer.Deserialize(reader);

【问题讨论】:

什么语言/平台?你用的是什么编码?你能发布你的代码吗? 反序列化?你的意思是解析?它的语言/目的是什么? 字符在什么上下文中出现?它实际上是有效的 XML,还是只是一个类似 XML? 它是有效的xml,当xml包含德/日字符时出现 XmlReader 确实可以处理所有字符,但这可能是编码问题。您能否发布完整的复制品以及完整的堆栈跟踪? 【参考方案1】:

我猜你遇到了编码问题,不是XMLReader,而是XmlSerializer。你可以将XmlTextWriter 和UTF8 编码与XmlSerializer 一起使用在下面的 sn-p 中(请参阅下面的通用方法以更好地实现它)。与元音变音 (äöü) 和其他 特殊字符 配合使用效果很好。

class Program

    static void Main(string[] args)
    
        SpecialCharacters specialCharacters = new SpecialCharacters  Umlaute = "äüö" ;

        // serialize object to xml

        MemoryStream memoryStreamSerialize = new MemoryStream();
        XmlSerializer xmlSerializerSerialize = new XmlSerializer(typeof(SpecialCharacters));
        XmlTextWriter xmlTextWriterSerialize = new XmlTextWriter(memoryStreamSerialize, Encoding.UTF8);

        xmlSerializerSerialize.Serialize(xmlTextWriterSerialize, specialCharacters);
        memoryStreamSerialize = (MemoryStream)xmlTextWriterSerialize.BaseStream;

        // converts a byte array of unicode values (UTF-8 enabled) to a string
        UTF8Encoding encodingSerialize = new UTF8Encoding();
        string serializedXml = encodingSerialize.GetString(memoryStreamSerialize.ToArray());

        xmlTextWriterSerialize.Close();
        memoryStreamSerialize.Close();
        memoryStreamSerialize.Dispose();

        // deserialize xml to object

        // converts a string to a UTF-8 byte array.
        UTF8Encoding encodingDeserialize = new UTF8Encoding();
        byte[] byteArray = encodingDeserialize.GetBytes(serializedXml);

        using (MemoryStream memoryStreamDeserialize = new MemoryStream(byteArray))
        
            XmlSerializer xmlSerializerDeserialize = new XmlSerializer(typeof(SpecialCharacters));
            XmlTextWriter xmlTextWriterDeserialize = new XmlTextWriter(memoryStreamDeserialize, Encoding.UTF8);

            SpecialCharacters deserializedObject = (SpecialCharacters)xmlSerializerDeserialize.Deserialize(xmlTextWriterDeserialize.BaseStream);
        
    


[Serializable]
public class SpecialCharacters

    public string Umlaute  get; set; 

我个人使用以下通用方法来序列化和反序列化 XML 和对象,并且还没有任何性能或编码问题。

public static string SerializeObjectToXml<T>(T obj)

    MemoryStream memoryStream = new MemoryStream();
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
    XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

    xmlSerializer.Serialize(xmlTextWriter, obj);
    memoryStream = (MemoryStream)xmlTextWriter.BaseStream;

    string xmlString = ByteArrayToStringUtf8(memoryStream.ToArray());

    xmlTextWriter.Close();
    memoryStream.Close();
    memoryStream.Dispose();

    return xmlString;


public static T DeserializeXmlToObject<T>(string xml)

    using (MemoryStream memoryStream = new MemoryStream(StringToByteArrayUtf8(xml)))
    
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

        using (StreamReader xmlStreamReader = new StreamReader(memoryStream, Encoding.UTF8))
        
            return (T)xmlSerializer.Deserialize(xmlStreamReader);
        
    


public static string ByteArrayToStringUtf8(byte[] value)

    UTF8Encoding encoding = new UTF8Encoding();
    return encoding.GetString(value);


public static byte[] StringToByteArrayUtf8(string value)

    UTF8Encoding encoding = new UTF8Encoding();
    return encoding.GetBytes(value);

【讨论】:

嗯。在 XmlTextWriter 中包装一个流,然后传递 writer.BaseStream 似乎你可以只传递没有 XmlTextWriter 的流。特别是因为 Deserialize 想要一个 XmlReader,而不是一个 writer,如果你打算走那条路的话。 @JesseChisholm 你是对的,这完全有道理。我还发现StreamReader 的实现要快一些。【参考方案2】:

对我有用的方法与@martin-buberl 的建议类似:

public static T DeserializeXmlToObject<T>(string xml)

    using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
    
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
        StreamReader reader = new StreamReader(memoryStream, Encoding.UTF8);
        return (T)xmlSerializer.Deserialize(reader);
    

【讨论】:

【参考方案3】:
    [XmlElement(ElementName = "Profiles")]
    //public ProfilesType[] Profiles  get; set; 
    public Profiles Profiles  get; set; 

上面试过了吗?

我没有检查过,但我想到了这一点。我设法对具有åäö等的数据进行反序列化。 你不是在谈论标记名吗?

【讨论】:

这对你有什么帮助.. 很抱歉没有得到你! 喜欢 2011årtal>,然后 ElementName = "årtal" 遗憾的是,årtal 导致了异常。

以上是关于使用特殊字符反序列化 XML 的快速方法的主要内容,如果未能解决你的问题,请参考以下文章

json特殊字符都有哪些

json格式如何读取有特殊字符的数据!内详!

如何处理JSON中的特殊字符

序列化时带有特殊字符的 XML 元素名称

c#中 如何解决xml格式的字符串中特殊字符

为啥html,xml的特殊符号转义不用斜杠,而要用& quot ;这样的奇怪形式?