如果在XElement
的内容中包含'\ x1A','\ x1B','\ x1C','\ x1D','\ x1E'或'\ x1F'等字符,我会收到异常
using System;
using System.Collections.Generic;
using System.Xml.Linq;
namespace LINQtoXMLInvalidChars
{
class Program
{
private static readonly IReadOnlyCollection<char> InvalidCharactersInXml = new List<char>
{
'<',
'>',
'&',
'\'',
'\"',
'\x1A',
'\x1B',
'\x1C',
'\x1D',
'\x1E',
'\x1F'
};
static void Main()
{
foreach (var c in InvalidCharactersInXml)
{
var xEl = new XElement("tag", "Character: " + c);
var xDoc = new XDocument(new XDeclaration("1.0", "utf-8", null), xEl);
try
{
Console.Write("Writing " + c + ": ");
Console.WriteLine(xDoc);
}
catch (Exception e)
{
Console.WriteLine("Oops. " + e.Message);
}
}
Console.ReadKey();
}
}
}
In an answer from Jon Skeet问题String escape into XML我读了
您在节点中设置文本,它将自动转义所需的任何内容。
所以现在我很困惑。我误解了什么吗?
一些背景信息:XElement
的字符串内容来自最终用户。我看到了两个使我的应用程序健壮的选项: 1)到Base-64对字符串进行编码,然后将其传递到XElement
2)以缩小接受的集合例如,字符字母数字字符。
答案 0 :(得分:4)
大多数这些字符根本不在XML 1.0中有效。我个人希望LINQ to XML无法生成以后无法解析的文档,但基本上你应该避免使用它们。
我还建议尽量避免使用\x
作为转义序列,更喜欢\u
- \x
将取“4个十六进制数字”这一事实可能非常令人困惑。
来自XML 1.0 spec:
Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
现在U + 000D和U + 000A是有趣的案例 - 它们不会在文本节点中转义;他们只是逐字被包括在内。当你解析节点时,它是否存在将取决于解析设置(以及它周围是否有非空白字符)。
就如何处理这种情况而言:你肯定有以下选项:
我们无法确定哪种情况最适合您的情景。