我正在使用 OpenXML Power Tools 在 Word Docx 文件中进行一些字符串替换,它按预期工作。但是,当我在替换中使用无效字符(例如 ampersand)时,事情就会中断,因此例如“Harry&Sally”将中断并生成无效文档。根据this post非法字符需要转换为xHHHH.
我找不到帖子中提到的 OOXML 子句的内容,因此无法适当地转义字符。
我希望有人对需要转义的字符有一些代码或见解。我也希望 OpenXML Power Tools 能以某种方式为我做这件事,但我似乎也无法在其中找到任何东西。
规范只是在谈论必须在 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
和" & "
分别。右尖括号 (>) 可以使用字符串" < "
表示,并且为了兼容性,必须使用" > "
进行转义或字符引用,当它出现在内容中的字符串" > "
中时,当该字符串未标记 CDATA 部分的结尾时。" ]]> "
要允许属性值同时包含单引号和双引号,撇号或单引号字符 (') 可以表示为
,双引号字符 (") 可以表示为" ' "
." " "
换句话说,转义以下字符:
' -> '
" -> "
> -> >
< -> <
& -> &
通常,您不会将它们编码为 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 也不是有效字符。
我在 Michael Edenfield 的回答的帮助下创建了一个扩展方法。非常自我解释......只需确保先替换&符号!否则你最终会错误地替换其他转义符号。
public static string EscapeXmlCharacters(this string input)
{
switch (input)
{
case null: return null;
case "": return "";
default:
{
input = input.Replace("&", "&")
.Replace("'", "'")
.Replace("\"", """)
.Replace(">", ">")
.Replace("<", "<");
return input;
}
}
}
.NET 小提琴:https://dotnetfiddle.net/PCqffy
我今天遇到了同样的问题,但是用
&
或 &
替换 & 没有用。
我在我的 Excel 文件中显示像 Harry &
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);
}