OpenXML 转义非法字符

问题描述 投票:0回答:3

我正在使用 OpenXML Power Tools 在 Word Docx 文件中进行一些字符串替换,它按预期工作。但是,当我在替换中使用无效字符(例如 ampersand)时,事情就会中断,因此例如“Harry&Sally”将中断并生成无效文档。根据this post非法字符需要转换为xHHHH.

我找不到帖子中提到的 OOXML 子句的内容,因此无法适当地转义字符。

我希望有人对需要转义的字符有一些代码或见解。我也希望 OpenXML Power Tools 能以某种方式为我做这件事,但我似乎也无法在其中找到任何东西。

c# openxml-sdk
3个回答
8
投票

规范只是在谈论必须在 XML 中转义的标准字符集。链接帖子中提到的 XML 规范来自 W3C,在这里.

有五个字符需要在它们出现在 XML 数据(名称、值等)中的任何位置进行转义,除非它们是 CDATA 部分的一部分。根据第 2.4 节:

与符号 (&) 和左尖括号 (<) must not appear in their literal form, except when used as markup delimiters, or within a comment, a processing instruction, or a CDATA section. If they are needed elsewhere, they must be escaped using either numeric character references or the strings

" &amp; "
" &lt; "
分别。右尖括号 (>) 可以使用字符串
" &gt; "
表示,并且为了兼容性,必须使用
 进行转义" &gt; "
或字符引用,当它出现在内容中的字符串
" ]]> "
中时,当该字符串未标记 CDATA 部分的结尾时。

要允许属性值同时包含单引号和双引号,撇号或单引号字符 (') 可以表示为

" &apos; "
,双引号字符 (") 可以表示为
" &quot; "
.

换句话说,转义以下字符:

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

通常,您不会将它们编码为 xHHHH,您会使用上面列出的 XML 实体,但两者都是允许的。您也不需要在每种情况下都对引号或右尖括号进行编码,仅当它们以其他方式表示 XML 语法时才进行编码,但始终这样做通常更安全。

XML 规范还包括可以出现在 XML 文档中的每个 Unicode 字符的列表,在第 2.2 节中:

字符 ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

该列表基本上包括 Basic 平面中的每个 Unicode 字符(您可能会遇到的每个字符),除了控制字符。只允许使用制表符、CR 和 LF 字符——ASCII 32(空格)以下的任何其他字符都需要转义。

列表中的大差距 (0xD800-0xDFF) 是代理编码值,无论如何都不应该单独出现,因为它们不是有效字符。最后两个 0xFFFE 和 0xFFFF 也不是有效字符。


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 小提琴:https://dotnetfiddle.net/PCqffy


0
投票

我今天遇到了同样的问题,但是用

&amp;
&#038;
替换 & 没有用。 我在我的 Excel 文件中显示像 Harry
&amp;
Sally 当您将 Harry & Sally 保存到单元格中时,我已经使用开放式 SDK 生产力工具检查了 Excel 2016 真正使用的是什么。它作为“Harry & Sally”存储在 SharedStringTable 中 所以我最终得到了两个不同的函数——一个用于数字、数据和时间列,一个用于所有字符/字符串列,其中我不替换 &。到目前为止,结果是应该的。我必须将许多数据从 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);
}
© www.soinside.com 2019 - 2024. All rights reserved.