我将一些XML发布到AWS中的API网关方法,该方法与SNS集成。然后,SQS队列订阅该主题;我有一个C#进程,间歇性地轮询队列,需要反序列化XML。
问题是,XML标签之间的空白最终会在某处沿着线进行编码,因此标签变为\t
,新行变为\r\n
。但这些最终成为字符串中的物理标记。
发布到API网关的示例XML:
<?xml version="1.0" encoding="utf-8"?>
<ProfileInformation>
<Username>bgs264</Username>
</ProfileInformation>
从SQS队列中读取的字符串:
<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ProfileInformation>\n\t<Username>bgs264</Username>\n</ProfileInformation>
请注意,声明中的属性最终为\"
,发布的空白最终为\t
,\r\n
等。
然而,这些不是“在调试器中出现的字符串,但它实际上是一个选项卡”,它们在字符串中实际上就像这样。
所以当我尝试反序列化时,使用
using (var reader = new StringReader(message))
var myObj = serializer.Deserialize(reader) as ProfileInformation);
我明白了:
InvalidOperationException:XML文档中存在错误(1,15)。
它指的是声明中的第一个\
字符,如version=\"1.0\"
我的直接想法是简单地将string.Replace
\t
用于清空字符串等,但这是不可接受的,因为用户的用户名实际上是bgs\t264
并且此处的替换可能会导致不一致。在这个例子中,我假设我会在消息中得到bgs\\t264
,所以替换会让我错误地使用bgs\264
。
所以我需要修复这些\n\t
字符,它们出现在XML标记之间。
对于它的价值,我还有一个用Go编写的lambda,它对此没有任何问题,只需将完全相同的字符串直接反序列化为XML。所以一定是可能的。
我最初的想法:
HttpUtility.DecodeHtml
尝试了这个,但我不认为它实际上是我试图解码的HTML!我猜,有些谷歌搜索似乎支持这个理论,你看到的消息已被转换为JSON,转义序列就是这样的结果。
理想的方法是调查并防止这种情况发生。我不太了解SNS建议并且你表明这是一个非首发,所以最简单的方法是在收到消息后撤销这个过程。
您可以使用像Json.NET这样的JSON库来执行此操作:
var jsonString = string.Format("\"{0}\"", message);
var xmlString = JsonConvert.DeserializeObject<string>(jsonString);
using (var reader = new StringReader(xmlString))
{
var profileInformation = (ProfileInformation) serializer.Deserialize(reader);
}