我很确定这个问题的答案是否定的,但是由于唯一的选择是我认为不优雅的代码,我想我应该把它扔出去,看看我是否错过了什么,同时希望这个问题没有被问到。
给定这个源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>
普通语言描述:
- Replace <move…>用结果处理名称匹配move的@elem属性和@item的元素匹配move的@item属性(例如,在本例中,元素[
]的内容被处理为由 )代替。 - 阻止步骤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:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kMover" match="move" use="concat(@elem,'+',@item)"/>
<xsl:key name="kToMove" match="*" use="concat(name(),'+',@item)"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="move">
<newContent>
<xsl:apply-templates mode="move" select=
"key('kToMove', concat(@elem,'+',@item))/node()"/>
</newContent>
</xsl:template>
<xsl:template match="p">
<block><xsl:apply-templates/></block>
</xsl:template>
<xsl:template match="b" mode="move">
<hmmm><xsl:apply-templates/></hmmm>
</xsl:template>
<xsl:template match="*[key('kMover', concat(name(),'+',@item))]"/>
</xsl:stylesheet>
当对提供的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>