我很确定这个问题的答案是否定的,但由于唯一的选择是我认为不优雅的代码,我想我会把它扔掉,看看我是否遗漏了一些东西,同时希望这个问题没有被问到。
鉴于此源 XML:
<root>
<p>Hello world</p>
<move elem="content" item="test"/>
<p>Another text node.</p>
<content item="test">I can't <b>figure</b> this out.</content>
</root>
我想要这个结果:
<root>
<block>Hello world</block>
<newContent>I can't <hmmm>figure</hmmm> this out.</newContent>
<block>Another text node.</block>
</root>
普通语言描述:
- 将 <move .../> 替换为名称与 move 的 @elem 属性匹配且其 @item 与 move 的 @item 属性匹配的元素的处理结果(例如,在这种情况下,元素 [<content>] 的内容被处理为<b> 替换为 <hmm>)。
- 防止步骤 1 中的元素以其原始文档顺序写入结果树
问题是输入的 XML 文档会相当复杂和多变。样式表是我正在扩展的第三方转换。为了使用基于模式的解决方案,我必须复制的模板在大小上非常重要,这对我来说似乎很不雅。例如,我知道这会起作用:
<xsl:template match="b">
<hmmm>
<xsl:apply-templates/>
</hmmm>
</xsl:template>
<xsl:template match="p">
<block>
<xsl:apply-templates/>
</block>
</xsl:template>
<xsl:template match="move">
<xsl:variable name="elem" select="@elem"/>
<xsl:variable name="item" select="@item"/>
<xsl:apply-templates select="//*[name()=$elem and @item=$item]" mode="copy-and-process"/>
</xsl:template>
<xsl:template match="content"/>
<xsl:template match="content" mode="copy-and-process">
<newContent><xsl:apply-templates/></newContent>
</xsl:template>
我想做的是让匹配“内容”的 <xsl:template> 对推送给它的节点敏感。因此,我可以有一个 <xsl:template match="content"/> 仅在从 <root> 而不是 <move> 推送的节点时执行(因此其匹配节点和子节点被抑制)。这样做的好处是,如果更新了第三方样式表的相关模板,我不必担心更新处理 <content> 节点的样式表的副本。我很确定这是不可能的,但我认为值得一问。