我目前正在维护一个大约一年前为工作编写的 Web 应用程序。基本上,它允许用户创建自定义 XHTML 报告模板。我使用XmlDocument
, XPathNavigator
, 等。人。用数据验证、清理和替换占位符。
它在大多数情况下都可以正常工作,但我刚刚意识到我实际上并没有用数据替换占位符元素,而是用数据文本替换占位符的文本。
人为的例子:
<span class="my-placeholder">{CompanyName}</span>
会成为...
<span class="my-placeholder">Castopulence</span>
这在过去并不是真正的问题,因为模板只被处理过一次;当用户选择针对一组选定的数据运行它时。但是,现在我们为他们提供了预览结果输出并在打印前对其进行修改的选项。这样做的结果是替换引擎不止一次地处理它:首先生成原始输出,然后再次“打印”修改后的输出。替换引擎找到实际上是数据的占位符,未能找到要替换的相应数据元素,并且处理失败并出现异常。
原始代码使用该XPathNavigator.InnerXml
属性将占位符元素的内容从“{CompanyName}”更改为“Castopulence”(例如):
placeholder.InnerXml = this.Server.HtmlEncode(value);
因此,如果我想彻底替换这个占位符元素,我会改用XPathNavigator.OuterXml
:
placeholder.OuterXml = this.Server.HtmlEncode(value);
这在大多数情况下似乎确实有效,或者至少我认为它有效,但看似随机的替换总是会导致System.InvalidOperationException
抛出消息“操作结果没有生成内容”。所以我不确定它们中的任何一个是否有效,但我认为它们是有效的,因为之前的替换不会引发异常。
我真的不知道这意味着什么,而且谷歌只有 4 个结果是异常消息的确切短语,每个结果都是我不会说的语言。谷歌翻译他们没有发现任何相关内容。
实验上我试过XPathNavigator.ReplaceSelf
,这似乎完成了同样的事情,但不幸的是,同样的异常从同一个内部调用中抛出。
两种情况下的堆栈跟踪:
在 System.Xml.DocumentXmlWriter.Close(WriteState currentState)
在 System.Xml.XmlWellFormedWriter.Close()
在 System.Xml.XPath.XPathNavigator.ReplaceSelf(XmlReader newNode)
在 System.Xml.XPath.XPathNavigator.ReplaceSelf(String newNode)
...截断私有应用程序符号...
MSDN 参考描述了它引发的ReplaceSelf
异常,但引发的唯一System.InvalidOperationException
异常是“XPathNavigator 未定位在元素、文本、处理指令或注释节点上”时。在 Visual Studio 调试器中,我可以确认它位于元素上。我的代码同意。指向占位符的XPathNavigator
' 实际上是System.Xml.XPath.XPathNodeIterator.Current
(所有这些都被添加到列表中,列表被转换为数组,并在替换阶段迭代)。
出了什么问题(异常实际上是什么意思),我该如何解决?
附加:实际上引发异常的类 ( System.Xml.DocumentXmlWriter
) 似乎没有记录在 MSDN 上(或者至少,我无法通过 Google 搜索或 MSDN 搜索找到它)。
追加:我已经确定导致问题的一个替换的数据只是一个空格(即" "
)。我不明白为什么这可能是一个问题XPathNavigator
,但显然它是......似乎也是一个空字符串(即,""
)。那么问题可能是试图用只有空格替换一个元素。我不明白为什么这应该是一个问题。