gpt4 book ai didi

c# - 无懈可击的 XMLException

转载 作者:太空狗 更新时间:2023-10-29 22:08:23 29 4
gpt4 key购买 nike

背景

我序列化了一个非常大的 List<string>使用此代码:

public static string SerializeObjectToXML<T>(T item)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
using (StringWriter writer = new StringWriter())
{
xs.Serialize(writer, item);
return writer.ToString();
}
}

并使用这段代码反序列化它:

public static T DeserializeXMLToObject<T>(string xmlText)
{
if (string.IsNullOrEmpty(xmlText)) return default(T);
XmlSerializer xs = new XmlSerializer(typeof(T));
using (MemoryStream memoryStream = new MemoryStream(new UnicodeEncoding().GetBytes(xmlText.Replace((char)0x1A, ' '))))
using (XmlTextReader xsText = new XmlTextReader(memoryStream))
{
xsText.Normalization = true;
return (T)xs.Deserialize(xsText);
}
}

但是当我反序列化它时我得到了这个异常:

XMLException: There is an error in XML document (217388, 15). '[]', hexadecimal value 0x1A, is an invalid character. Line 217388, position 15.

at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)

at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader)

问题

为什么是 xmlText.Replace((char)0x1A, ' ') 线路不工作,这是什么魔法?

一些约束

  • 我的代码使用 C#,框架 4,在 VS2010 Pro 中构建。
  • 我无法在 Debug模式下查看 xmlText 的值,因为 List<string>太大了,监 window 口只显示 Unable to evaluate the expression. Not enough storage is available to complete this operation.错误信息。

最佳答案

我想我已经找到了问题所在。默认情况下,XmlSerializer 将允许您生成无效的 XML。

给定代码:

var input = "\u001a";

var writer = new StringWriter();
var serializer = new XmlSerializer(typeof(string));
serializer.Serialize(writer, input);

Console.WriteLine(writer.ToString());

输出是:

<?xml version="1.0" encoding="utf-16"?>
<string>&#x1A;</string>

这是无效的 XML。根据 XML 规范,所有字符引用都必须指向有效的字符。有效字符是:

#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

如您所见,U+001A(以及所有其他 C0/C1 控制字符)不允许作为引用,因为它们不是有效字符。

解码器给出的错误信息有点误导,如果它说存在无效的字符引用会更清楚。

您可以执行多种操作。

1) 首先不要让 XmlSerializer 创建无效文档

您可以使用 XmlWriter,默认情况下不允许使用无效字符:

var input = "\u001a";

var writer = new StringWriter();
var serializer = new XmlSerializer(typeof(string));

// added following line:
var xmlWriter = XmlWriter.Create(writer);

// then, write via the xmlWriter rather than writer:
serializer.Serialize(xmlWriter, input);

Console.WriteLine(writer.ToString());

这将在序列化发生时抛出异常。必须对此进行处理并显示适当的错误。

这可能对您没有用,因为您的数据已经存储了这些无效字符。

或 2) 删除对这个无效字符的引用

也就是说,不是 .Replace((char)0x1a, ' '),它目前实际上并没有替换文档中的任何内容,而是使用 .Replace("& #x1A;", "")。 (这不是不区分大小写的,但它是 .NET 生成的内容。更可靠的解决方案是使用不区分大小写的正则表达式。)


顺便说一句,XML 1.1 实际上允许引用控制字符,只要它们是引用而不是文档中的普通字符。除了 .NET XmlSerializer 不支持版本 1.1 之外,这将解决您的问题。

关于c# - 无懈可击的 XMLException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9798033/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com