首页 文章

XML中的字符无效

提问于
浏览
192

我目前正在处理一些XML .

我有节点,如下所示:

<node>This is a string</node>

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

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

这是因为&

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

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

15 回答

  • 0

    唯一的非法字符是 &<> (以及属性中的 "' ) .

    它们使用XML entities进行转义,在这种情况下,您希望 && .

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

  • 7

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

    @dolmen Invalid Characters in XML提供的答案仍然有效,但需要使用XML 1.1规范进行更新 .

    1.无效字符

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

    1.1.在XML 1.0中

    允许字符的全局列表是:

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

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

    1.2.在XML 1.1中

    允许字符的全局列表是:

    [2] Char :: = [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] / *任何Unicode字符,不包括代理块,FFFE和FFFF . * / [2a] RestrictedChar :: = [#x1-#x8] | [#xB-#xC] | [#xE-#x1F] | [#x7F-#x84] | [#x86的#x9F]

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

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

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

    2.需要转义的字符(以获取格式正确的文档):

    < 必须使用 &lt; 实体进行转义,因为它被假定为标记的开头 .

    & 必须使用 &amp; 实体进行转义,因为它假定为实体引用的开头

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

    ' 应该使用 &apos; 实体进行转义 - 在单引号中定义的属性中必须使用 - 但强烈建议始终对其进行转义 .

    " 应该使用 &quot; 实体进行转义 - 在双引号内定义的属性中是必需的,但强烈建议始终将其转义 .

  • 17

    有效字符列表位于XML specification中:

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

    这是一个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, ""); 
    }
    
  • 57

    预先声明的字符是:

    & < > " '
    

    http://xml.silmaril.ie/specials.html

  • 5

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

    WebUtility.HtmlEncode(stringWithStrangeChars)
    
  • -3

    除了potame的答案,如果你想要使用CDATA块逃脱 .

    如果你把你的文字 in a CDATA block then you don't need to use escaping . 在这种情况下,您可以使用 all characters in the following range

    graphical representation of possible characters

    注意:除此之外,您不能使用 ]]> 字符序列 . 因为它会匹配CDATA块的末尾 .

    如果仍然存在无效字符(例如控制字符),则可能最好使用某种编码(例如base64) .

  • 168

    使用XmlConvert.IsXmlChar Method删除C#中不正确的XML字符的另一种方法(自.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小提琴 - https://dotnetfiddle.net/v1TNus

    例如,垂直选项卡symbol(\ v)对XML无效,它是有效的UTF-8,但不是有效的XML 1.0,甚至许多库(包括libxml2)都会错过它并静默输出无效的XML .

  • 1

    这个答案对我有用

    string code = Regex.Replace(item.Code, @"[\u0000-\u0008,\u000B,\u000C,\u000E-\u001F]", "");
    

    详情link to Blog

  • 1

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

  • 176

    在Woodstox XML处理器中,无效字符按此代码分类

    if (c == 0) {
        throw new IOException("Invalid null character in text to output");
    }
    if (c < ' ' || (c >= 0x7F && c <= 0x9F)) {
        String msg = "Invalid white space character (0x" + Integer.toHexString(c) + ") in text to output";
        if (mXml11) {
            msg += " (can only be output using character entity)";
        }
        throw new IOException(msg);
    }
    if (c > 0x10FFFF) {
        throw new IOException("Illegal unicode character point (0x" + Integer.toHexString(c) + ") to output; max is 0x10FFFF as per RFC");
    }
    /*
     * Surrogate pair in non-quotable (not text or attribute value) content, and non-unicode encoding (ISO-8859-x,
     * Ascii)?
     */
    if (c >= SURR1_FIRST && c <= SURR2_LAST) {
        throw new IOException("Illegal surrogate pair -- can only be output via character entities, which are not allowed in this content");
    }
    throw new IOException("Invalid XML character (0x"+Integer.toHexString(c)+") in text to output");
    

    来自here

  • 0
    ampersand (&) is escaped to &amp;
    
    double quotes (") are escaped to &quot;
    
    single quotes (') are escaped to &apos; 
    
    less than (<) is escaped to &lt; 
    
    greater than (>) is escaped to &gt;
    

    在C#中,使用System.Security.SecurityElement.Escape或System.Net.WebUtility.HtmlEncode来转义这些非法字符 .

    string xml = "<node>it's my \"node\" & i like it 0x12 x09 x0A  0x09 0x0A <node>";
    string encodedXml1 = System.Security.SecurityElement.Escape(xml);
    string encodedXml2= System.Net.WebUtility.HtmlEncode(xml);
    
    
    encodedXml1
    "&lt;node&gt;it&apos;s my &quot;node&quot; &amp; i like it 0x12 x09 x0A  0x09 0x0A &lt;node&gt;"
    
    encodedXml2
    "&lt;node&gt;it&#39;s my &quot;node&quot; &amp; i like it 0x12 x09 x0A  0x09 0x0A &lt;node&gt;"
    
  • 2

    有人试过这个 System.Security.SecurityElement.Escape(yourstring) ?这将用有效的等效字符替换字符串中的无效XML字符

  • 1

    总之,文本中的有效字符是:

    • 标签,换行和回车;

    • 所有非控制字符均有效 except &和<;
      如果遵循]],则

    • 无效 .

    XML规范的2.2和2.4节提供了详细的答案:

    Characters

    合法字符包括制表符,回车符,换行符以及Unicode和ISO / IEC 10646的合法字符

    Character data

    &符号(&)和左尖括号(<)不得以其文字形式出现,除非用作标记分隔符,或用于注释,处理指令或CDATA部分 . 如果在其他地方需要它们,则必须使用数字字符引用或字符串“&”和“<”分别进行转义 . 右尖括号(>)可以使用字符串“>”表示,并且为了兼容性,当它出现在字符串“]]>”内容中时,必须使用“>”或字符引用进行转义 . string不标记CDATA部分的结尾 .

  • 2

    对于XSL(在非常懒惰的日子里),我使用:

    capture="&amp;(?!amp;)" capturereplace="&amp;amp;"
    

    翻译所有未签署的&-signs;适当的 .

    我们有输入在CDATA中的情况,但使用XML的系统不考虑它 . 这是一个草率的修复,要小心......

相关问题