我正在使用一些包含字符串的XML:

<node>This is a string</node>

我传递给节点的一些字符串将有&,#,$等字符:

<node>This is a string & so is this</node>

由于&,这是无效的。

我不能在CDATA中包装这些字符串,因为它们需要这样。我尝试寻找一个字符列表,这些字符不能放在XML节点中,而不能放在CDATA中。

有人能给我指个方向或者给我一份非法字符的列表吗?


当前回答

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

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

其他回答

有人尝试过这个system . security . securityelelement . escape (yourstring)吗? 这将用有效的等效字符替换字符串中的无效XML字符。

唯一的非法字符是&,<和>(以及属性中的"或',这取决于使用哪个字符来分隔属性值:attr="必须使用"这里,' is allowed '和attr='必须使用&apos;在这里,“is allowed”)。

它们是用XML实体转义的,这里你需要&&。

实际上,您应该使用一个工具或库来为您编写XML,并为您抽象这类东西,这样您就不必担心了。

对于Java人来说,Apache有一个实用程序类(StringEscapeUtils),它有一个帮助方法escapeXml,可以用来使用XML实体转义字符串中的字符。

好的,让我们把角色的问题分开

在任何XML文档中都无效。 需要逃脱。

“https://stackoverflow.com/questions/730133/invalid-characters-in-xml/5110103#5110103”中@dolmen提供的答案仍然有效,但需要使用XML 1.1规范进行更新。

1. 无效字符

这里描述的字符是允许在XML文档中插入的所有字符。

1.1. 在XML 1.0中

参考:参见XML推荐1.0,§2.2字符

允许字符的全局列表是:

[2] Char::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /*任何Unicode字符,不包括代理块FFFE和FFFF。* /

基本上,控制字符和超出Unicode范围的字符是不允许的。 这也意味着调用字符实体&#x3;是被禁止的。

1.2. XML 1.1中

参考:参见XML推荐1.1、§2.2字符和1.3 XML 1.1的基本原理和更改列表

允许字符的全局列表是:

[2] Char::= [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /*任何Unicode字符,不包括代理块FFFE和FFFF。* /

(2a) RestrictedChar ::= [# 已发现x1 - x8] | [# - # xC] | [/ xE - x1F] | [/ x7F - x84] | [/ x86 - x9F]

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

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

还可以注意到,并非所有解析器都考虑到这一点,带有控制字符的XML文档可能会被拒绝。

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

<必须用&#60转义;实体,因为它被假定为标记的开始。

&必须用&#38转义;实体,因为它被假定为实体引用的开始

>应该用&#62;实体。它不是强制性的——它取决于上下文——但强烈建议避免使用它。

'应该用&#39;Entity——在单引号内定义的属性中是强制的,但强烈建议总是转义它。

"应该用&#34;Entity——在双引号中定义的属性中是强制的,但强烈建议总是转义它。

在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());
}

或者你可以检查所有字符都是xml有效的:

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

net小提琴

例如,垂直制表符(\v)对于XML无效,它是有效的UTF-8,但不是有效的XML 1.0,甚至许多库(包括libxml2)都会遗漏它并无声地输出无效的XML。