OpenXML转义非法字符

7
我正在使用OpenXML Power Tools在Word Docx文件中进行一些字符串替换,它能够按预期工作。但是当我进行不合法字符的替换,例如和号时,会发生错误,因此例如“Harry & Sally”会破坏并生成无效的文档。根据这篇文章,需要将非法字符转换为xHHHH。
我很难找到帖子中提到的OOXML条款内容,并适当转义字符。
我希望有人可以提供代码或洞察什么字符需要转义。我也希望OpenXML Power Tools在某种程度上能够为我完成这项工作,但我似乎也找不到其中任何内容。

如果某些东西没有按预期工作,您可能有一些代码需要展示。请将此代码片段添加到您的问题中。 - Victor Zakharov
3个回答

9
这个规范只是讨论在XML中必须转义的标准字符集。链接帖子中提到的XML规范是W3C的规范,可在此处找到
除非它们是CDATA节的一部分,否则任何出现在XML数据(名称、值等)中的五个字符都需要进行转义。根据第2.4节的规定:
“&”字符和左尖括号(“<”)不能直接出现,除非它们用作标记分隔符或在注释、处理指令或CDATA节中使用。如果需要在其他地方使用它们,则必须使用数字字符引用或字符串“&amp;”和“&lt;”进行转义。右尖括号(“>”)可以使用字符串“&gt;”表示,并且必须在内容中出现字符串“]]>”时进行转义,除非该字符串标记了CDATA节的结尾,为确保兼容性,可以使用“&gt;”或字符引用进行转义。

为了允许属性值同时包含单引号和双引号,“'”或单引号字符可以表示为“&apos;”,双引号字符可以表示为“&quot;”。

' -> &apos;
" -> &quot;
> -> &gt;
< -> &lt;
& -> &amp;

通常情况下,您不会将它们编码为xHHHH,而是使用上面列出的XML实体,但两者都可以。您也不需要在每种情况下都对引号或右尖括号进行编码,只有在它们表示XML语法时才需要,但通常最好始终这样做。
XML规范还包括可以出现在XML文档中的每个Unicode字符的列表,在第2.2节中:
Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
该列表基本包括基本平面中的每个Unicode字符(您可能会遇到的每个字符),除了控制字符。只允许制表符、CR和LF字符 - 任何其他ASCII 32(空格)以下的字符都需要转义。
列表中的巨大间隙(0xD800-0xDFF)用于代理编码值,无论如何它们都不应单独出现,因为它们不是有效字符。最后两个字符0xFFFE和0xFFFF也不是有效字符。

3
你可能想为省略的分号补上撇号和引号。 - TheEdge
@TheEdge 我已经添加了它们。 - Jonathan Wilson

0
我借鉴了Michael Edenfield的答案创建了一个扩展方法。非常简单易懂...只要确保先替换掉&符号!否则你会错误地替换其他转义符号。
public static string EscapeXmlCharacters(this string input)
{
    switch (input)
    {
        case null: return null;
        case "": return "";
        default:
        {
            input = input.Replace("&", "&amp;")
                .Replace("'", "&apos;")
                .Replace("\"", "&quot;")
                .Replace(">", "&gt;")
                .Replace("<", "&lt;");

            return input;
        }
    }
}

.NET Fiddle: https://dotnetfiddle.net/PCqffy

.NET Fiddle:https://dotnetfiddle.net/PCqffy


0
今天我遇到了同样的问题,但是用&amp;&#038;替换&符号并没有起作用。在我的Excel文件中显示为Harry &amp; Sally。我使用了Open SDK生产力工具检查了一下当你将Harry & Sally保存到单元格中时,Excel 2016实际上使用的是什么。它存储在SharedStringTable中为"Harry & Sally"。所以我最终得到了两个不同的函数 - 一个用于数字、日期和时间列,另一个用于所有字符/字符串列,在其中我不替换&。到目前为止,结果是应该的。我需要从CRM系统导出许多数据到几个Excel文件中。这个函数通常是从OpenSDKXML SDK文档中获取的。我只修改了第二个函数中的正则表达式字符串。
private static string ReplaceHexadecimalSymbols(string txt)
{
    string r = "[\x00-\x08\x0B\x0C\x0E-\x1F\x26]";
    return Regex.Replace(txt, r, "", RegexOptions.Compiled);
}

private static string ReplaceHexadecimalSymbolsinString(string txt)
{
    string r = "[\x00-\x08\x0B\x0C\x0E-\x1F]";
    return Regex.Replace(txt, r, "", RegexOptions.Compiled);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接