如何在XSLT中从另一个模板调用模板?

问题描述 投票:1回答:1

我有以下xml:

<rootelement>
   <parentelement>
      <mytype>123</mytype>
      <myvalue>abc</myvalue>
   </parentelement>
   <parentelement>
      <mytype>234</mytype>
      <myvalue>xyz</myvalue>
   </parentelement>
</rootelement>

首先,我应用使用字典的模板来更改mytype的值:

   <parentelement>
      <mytype>Mapped1</mytype>
      <myvalue>abc</myvalue>
   </parentelement>
   <parentelement>
      <myvalue>qwe</myvalue>
   </parentelement>

如果mytype标签被删除,我想应用下一个删除整个parentelement的转换。换句话说,我希望第二个转换创建以下XML:

   <parentelement>
      <mytype>Mapped1</mytype>
      <myvalue>abc</myvalue>
   </parentelement>

我尝试在第一个模板的末尾添加以下内容:

<xsl:template match="mytype">
    ...
    <xsl:call-template name="mytypetemplate"/>
</xsl:template>

使用以下模板作为第二个模板:

<xsl:template name="mytypetemplate" match="/rootelement/parentelement[not(mytype) or mytype[not(node())]]"/>

但我得到的结果是它执行第一个模板,但不执行第二个模板。换句话说,它删除mytype(第一个模板),但它没有删除没有mytype(第二个模板)的元素的整个parentelement。如何在第一个变换之后应用第二个变换?

谢谢!

xml templates xslt
1个回答
2
投票

您可以使用modes(https://www.w3.org/TR/xslt/#element-mode)分隔处理步骤,并使用变量来存储和使用临时结果,在示例中

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

    <xsl:mode on-no-match="shallow-copy"/>
    <xsl:mode name="step1" on-no-match="shallow-copy"/>

    <xsl:variable name="step1-result">
        <xsl:apply-templates mode="step1"/>
    </xsl:variable>

    <xsl:template match="parentelement[myvalue = 'abc']/mytype" mode="step1"/>

    <xsl:template match="/">
        <xsl:apply-templates select="$step1-result/node()"/>
    </xsl:template>

    <xsl:template match="parentelement[not(mytype)]"/>

</xsl:stylesheet>

模式step1mytypes中删除parentelement元素,myvalueabc,默认模式处理变量step1-result中创建的临时结果,以消除任何没有parentelement子项的mytypes。

所以对于输入

<?xml version="1.0" encoding="UTF-8"?>
<rootelement>
    <parentelement>
        <mytype>123</mytype>
        <myvalue>abc</myvalue>
    </parentelement>
    <parentelement>
        <mytype>234</mytype>
        <myvalue>xyz</myvalue>
    </parentelement>
</rootelement>

然后结果是

<rootelement>

        <parentelement>
                <mytype>234</mytype>
                <myvalue>xyz</myvalue>
        </parentelement>
</rootelement>

http://xsltfiddle.liberty-development.net/b4GWV2在线。

一个轻微的变化是

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>
  <xsl:mode name="step1" on-no-match="shallow-copy"/>

  <xsl:template match="parentelement[myvalue = 'abc']/mytype" mode="step1"/>

  <xsl:template match="/">
    <xsl:variable name="step1-result">
      <xsl:apply-templates mode="step1"/>
    </xsl:variable>
    <xsl:apply-templates select="$step1-result/node()"/>
  </xsl:template>

  <xsl:template match="parentelement[not(mytype)]"/>

</xsl:stylesheet>

你可以在http://xsltfiddle.liberty-development.net/b4GWV2/1在网上看到。

© www.soinside.com 2019 - 2024. All rights reserved.