是否可以在不使用xsl:param的情况下使xsl:template对推出节点敏感?



我很确定这个问题的答案是否定的,但是由于唯一的选择是我认为不优雅的代码,我想我应该把它扔出去,看看我是否错过了什么,同时希望这个问题没有被问到。

给定这个源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>

普通语言描述:

  1. Replace <move…>用结果处理名称匹配move的@elem属性和@item的元素匹配move的@item属性(例如,在本例中,元素[]的内容被处理为)代替。
  2. 阻止步骤1中的元素以其原始文档顺序
  3. 写入结果树

问题是输入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>

我想做的是有匹配的"内容"对节点向其推送的内容敏感。因此,我可以写入只有当节点从root 而不是"动"。这样做的好处是,如果更新了第三方样式表的相关模板,我就不必担心更新处理节点。我很确定这是不可能的,但我觉得值得问一下。

:

<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>

最新更新