如何在同一匹配上处理多个XSLT复制语句?

时间:2011-12-16 18:06:36

标签: xslt copy

是否有任何XSLT语句将在同一样式表中考虑其他XSLT语句而执行?

例如,如果我有两个与同一节点匹配的复制语句(但只希望一个包含在BOTH复制语句中声明的修改的复制节点)是否有一个语句可以执行此操作?

假设我不能将所有转换放在一个复制节点中,而是必须使用两个或更多个。

---更清晰的例子---

//XML
<toy></toy>

//XSLT
<xsl:template  match="toy">
<xsl:copy>
    <xsl:attribute name="label">SOME TOY</xsl:attribute>
</xsl:copy>
</xsl:template>


<xsl:template  match="toy">
<xsl:copy>
    <xsl:apply-templates select="@*" />
      <xsl:element name="range">
        <xsl:element name="min">200001</xsl:element>
        <xsl:element name="max">999999</xsl:element>
      </xsl:element>
</xsl:copy>
</xsl:template>

我想要的结果是一个新的玩具节点,它被复制到一个新的文件中,它同时应用了两个东西,如下所示:

<toy label='SOME TOY'>
  <range>
    <min>200001</min>
    <max>999999</max>
  </range>
</toy>

不是两个不同的副本

这可能吗?有没有什么方法可以重做第一个模板,以便产生这一结果?

1 个答案:

答案 0 :(得分:2)

XSLT规范中有规则,禁止这样做 - Conflict Resolution for Template Rules

如果节点适合多个模板 - 将只执行一个模板 - 与模板导入优先级,优先级或文档顺序等相关。

但您可以将其与命名的模板分开:

<xsl:template match="toy">
  <xsl:call-template name="toyAttribute" />
  <xsl:call-template name="toyElements" />
</xsl:template>

<xsl:template name="toyAttribute">
  <xsl:copy>
    <xsl:attribute name="label">SOME TOY</xsl:attribute>
  </xsl:copy>
</xsl:template>

<xsl:template name="toyElements">
  <xsl:copy>
    <xsl:apply-templates select="@*" />
    <xsl:element name="range">
      <xsl:element name="min">200001</xsl:element>
      <xsl:element name="max">999999</xsl:element>
    </xsl:element>
 </xsl:copy>
</xsl:template>

<强>更新 如果您只询问更新&lt; toy&gt;具有属性和元素的节点,您不需要单独的模板:

<!--toy template -->
<xsl:template match="/toys/toy">
    <!--copy toy node with namespaces -->
    <xsl:copy>
        <!-- copy toy node attributes -->
        <xsl:apply-templates select="@*" />
        <!-- add new attribute or xsl:call-template name="toyAttribute"-->
        <xsl:attribute name="label">SOME TOY</xsl:attribute>
        <!-- copy toy node child elements -->
        <xsl:apply-templates select="node()" />
        <!-- add new elements - or xsl:call-template name="toyElements"-->
        <xsl:element name="range">
            <xsl:element name="min">200001</xsl:element>
            <xsl:element name="max">999999</xsl:element>
        </xsl:element>
    </xsl:copy>
</xsl:template>

<!--Copy node content -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

对于XML:

<?xml version="1.0" encoding="UTF-8"?> 
<toys>
    <toy name="a">
        <toy-part/>
    </toy>
    <toy name="b">
        <toy-part/>
    </toy>
</toys>

将给出以下结果:

<?xml version="1.0" encoding="utf-8"?><toys>
    <toy name="a" label="SOME TOY">
        <toy-part/>
        <range>
           <min>200001</min>
           <max>999999</max>
        </range>
    </toy>
    <toy name="b" label="SOME TOY">
        <toy-part/>
        <range>
           <min>200001</min>
           <max>999999</max>
        </range>
    </toy>
</toys>