XML中的字符无效

Rai*_*Son 210 xml illegal-characters

我目前正在处理一些XML.

我有节点,如下所示:

<node>This is a string</node>
Run Code Online (Sandbox Code Playgroud)

我传递给节点的一些字符串将包含&,#,$等字符.

<node>This is a string & so is this</node>
Run Code Online (Sandbox Code Playgroud)

这是因为&

我无法将这些字符串包装在CDATA中,因为它们需要保持原样.我试过在线查找一些字符列表,这些字符无法放入XML节点而不是CDATA.

任何人都可以指向一个方向或向我提供非法字符列表吗?

pot*_*ame 198

好的,让我们将(1)任何XML文档中完全无效的字符和(2)需要转义的字符分开:

@dolmen提供的答案XML中的无效字符仍然有效,但需要使用XML 1.1规范进行更新.

1.无效字符

此处描述的字符是允许插入XML文档的所有字符.

1.1.在XML 1.0中

允许字符的全局列表是:

[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

基本上,不允许使用Unicode范围之外的控制字符和字符.这也意味着&#x3;禁止调用例如字符实体.

1.2.在XML 1.1中

允许字符的全局列表是:

[2] Char ::= [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

[2a] RestrictedChar ::= [#x1-#x8] | [#xB-#xC] | [#xE-#x1F] | [#x7F-#x84] | [#x86-#x9F]

这个XML建议的修订扩展了允许的字符,因此允许控制字符,并考虑到Unicode标准的新版本,但仍然不允许这些:NUL(x00),xFFFE,xFFFF ......

但是,不鼓励使用控制字符和未定义的Unicode char.

还可以注意到,所有解析器并不总是考虑到这一点,并且可能拒绝具有控制字符的XML文档.

2.需要转义的字符(以获得格式良好的文档):

<必须使用转义&lt;实体,因为它被认为是一个标签的开始.

&必须使用转义&amp;实体,因为它被认为是开始一个实体引用

>应进行转义&gt;实体.它不是强制性的 - 它取决于上下文 - 但强烈建议逃避它.

'应该用转义&apos;实体-在单引号内定义的属性强制性的,但它强烈建议总是逃避它.

"应该用转义&quot;实体-在双引号内定义的属性强制性的,但它强烈建议总是逃避它.

  • *”,但强烈建议始终逃避它“* - 你能澄清一下吗?谁建议这样做,为什么?(在我看来,在语法允许的地方使用文字引号并没有什么问题。) (3认同)
  • 对于 2.:有关详细信息,请参阅 /sf/ask/76436181/​​haracters-do-i-need-to-escape-in​​-xml-documents。这 5 个字符并不需要“总是”被转义,只是在某些情况下。 (3认同)

dol*_*men 171

有效字符列表在XML规范中:

Char       ::=      #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]  /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */
Run Code Online (Sandbox Code Playgroud)

  • @xamde该列表很好,但它只显示可用于启动XML元素的字符.手头的问题一般是哪些字符在XML文件中有效.某些字符在任何地方都是不允许的. (8认同)
  • 您应该注意,虽然它们是合法字符,但在某些情况下必须转义`&<>"'`. (7认同)
  • 在这种情况下,"合法"意味着他们的最终解码值是合法的,而不是它们在流中是合法的.如上所述,一些法律价值必须在流中转义. (7认同)

Wel*_*bog 135

唯一的非法字符&,<并且>(和"'在属性).

他们使用逃脱XML实体,在你想这种情况下&amp;&.

但实际上,你应该使用一个为你编写XML的工具或库,并为你抽象出这种东西,这样你就不用担心了.

  • 某些控件字符也是不允许的.请参阅下面的答案. (79认同)
  • 实际上这并不完全正确.许多较低的ascii字符也是无效的.如果您尝试将0x03写入Xml文档,通常会出现错误,如果您设法将其正确地转义为XML文档,则大多数查看者会抱怨无效字符.边缘情况但确实发生了. (41认同)
  • 这个答案是绝对错误的.这是我的XML异常,0x12非法字符'System.Xml.XmlException:'',十六进制值0x12,是无效字符' (15认同)
  • 在另一个方向上也是错的; 除了遗漏每一个非法字符外,它声称非法的字符是完全合法的,尽管在上下文中具有特殊含义. (8认同)
  • 在XML 1.0中有许多非法字符.实际上,即使对大多数控制字符使用字符实体也会在解析时导致错误. (5认同)
  • 0x1f 在 XML 1.0 中也是无效字符。尽管在 XML 1.1 中它是有效的。 (2认同)
  • 还有 0x0B 或“\v”,一个垂直制表符。 (2认同)

mat*_*eca 58

这是一个C#代码,用于从字符串中删除XML无效字符并返回新的有效字符串.

public static string CleanInvalidXmlChars(string text) 
{ 
    // From xml spec valid chars: 
    // #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]     
    // any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. 
    string re = @"[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]"; 
    return Regex.Replace(text, re, ""); 
}
Run Code Online (Sandbox Code Playgroud)

  • 对于Java,正则表达式模式将是相同的.然后,您可以在类String中使用名为replaceAll的方法,该方法期望将正则表达式模式作为参数.检查一下:http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#replaceAll%28java.lang.String,%20java.lang.String%29 (6认同)
  • 我的字符串中有这样的无效字符:SUSITARIMO D&#x5; L DARBO SUTARTIES此代码不会删除&#x5; 因此xml文档无法初始化. (2认同)
  • 我相信您不能只是将这种模式放入 .NET 正则表达式构造函数中。我认为它不会将 `\u10000` 和 `\u10FFFF` 识别为单个字符,因为它们每个都需要两个 utf-16 `char` 实例,并且根据 [docs](https://docs.microsoft.com/ en-us/dotnet/standard/base-types/character-escapes-in-regular-expressions)可能不会超过 4 位数字。`[\u10000-\u10FFFF]` 很可能被解析为 [`\u1000`, `0-\u10FF`, `F`, `F`],这看起来很奇怪但合法。 (2认同)

小智 7

另一种在C#中逃避可能不需要的XML/XHTML字符的简单方法是:

WebUtility.HtmlEncode(stringWithStrangeChars)
Run Code Online (Sandbox Code Playgroud)

  • 他写的是Xml而不是Html。 (2认同)

Ale*_*hev 7

在 C# 中删除不正确 XML 字符的另一种方法是使用XmlConvert.IsXmlChar(自 .NET Framework 4.0 起可用)

public static string RemoveInvalidXmlChars(string content)
{
   return new string(content.Where(ch => System.Xml.XmlConvert.IsXmlChar(ch)).ToArray());
}
Run Code Online (Sandbox Code Playgroud)

或者您可以检查所有字符是否都是 XML 有效的:

public static bool CheckValidXmlChars(string content)
{
   return content.All(ch => System.Xml.XmlConvert.IsXmlChar(ch));
}
Run Code Online (Sandbox Code Playgroud)

.Net小提琴

例如,垂直制表符 ( \v) 对 XML 无效,它是有效的 UTF-8,但不是有效的 XML 1.0,甚至许多库(包括 libxml2)都错过了它并静默输出无效的 XML。


bvd*_*vdb 6

除了potame的答案之外,如果您确实想使用CDATA块进行转义。

如果将文本放在CDATA块中,则无需使用转义。在这种情况下,您可以使用以下范围内的所有字符

可能字符的图形表示

注意:最重要的是,不允许使用]]>字符序列。因为它将与CDATA块的末尾匹配。

如果仍然有无效字符(例如控制字符),那么最好使用某种编码(例如base64)。

  • 确切地说,这不是我写的吗?引用:“所有字符*在以下范围内*”。我的意思是,只有此特定范围内的字符。不允许使用其他字符。- 完全同意 ; 但我不理解反对意见。-虽然没有难过的感觉。 (4认同)
  • 不管是否在CDATA块中,XML中都禁止某些字符。 (3认同)