循环没有上下文节点更改

时间:2016-09-06 15:11:50

标签: xslt xslt-2.0

需要帮助。请在“部门”模板中查看我的评论。在这里,我想多次重复相同的处理(基于$ time变量)。如果我使用call-template并传递当前节点,那么我就无法重新使用已经编写的子模板规则。有什么好办法实现这一目标。

XML

   <?xml version="1.0" encoding="UTF-8"?>
  <emp>
    <department name="science">
      <empname>Rob</empname>
      <empno>01</empno>
      <emptype>regular</emptype>
   </department>
  </emp>

XSLT

  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      exclude-result-prefixes="xs"
      version="2.0">
      <xsl:param name="times" select="'a1,b1,c1'"></xsl:param>
      <xsl:template match="/">        
          <xsl:apply-templates/>
      </xsl:template>
      <xsl:template match="department">
          <xsl:copy>
              <xsl:copy-of select="@*"></xsl:copy-of>
              <xsl:apply-templates select="empname"/>
              <someelements></someelements>
              <xsl:apply-templates select="empno"/>
              <instances>
              <xsl:for-each select="tokenize($times, ',\s*')">
                  <xsl:variable name="time" select="."/>
                  <iemployee time="{$time}">
                      <!-- I want to repat the the "department" template here -->
                  </iemployee>
              </xsl:for-each>
              </instances>
          </xsl:copy>
      </xsl:template>
      <xsl:template match="empname">
          <employeename>
              <xsl:apply-templates/>
          </employeename>
      </xsl:template>
      <xsl:template match="empno">
          <employeenumber>
              <xsl:apply-templates/>
          </employeenumber>
      </xsl:template>
  </xsl:stylesheet>

输出

<department name="science">
<employeename>Rob</employeename>
<someelements/>
<employeenumber>01</employeenumber>
<instances>
    <iemployee time="a1">
        <employeename>Rob</employeename>
        <someelements/>
        <employeenumber>01</employeenumber>
    </iemployee>
    <iemployee time="b1">
        <employeename>Rob</employeename>
        <someelements/>
        <employeenumber>01</employeenumber>
    </iemployee>
    <iemployee time="c1">
        <employeename>Rob</employeename>
        <someelements/>
        <employeenumber>01</employeenumber>
    </iemployee>
</instances>

2 个答案:

答案 0 :(得分:2)

我认为你需要另一种模式,使用不同的模式:

  <xsl:template match="department">
      <xsl:copy>
          <xsl:copy-of select="@*"></xsl:copy-of>
          <xsl:apply-templates select="." mode="content"/> 
          <instances>
          <xsl:variable name="dep" select="."/>
          <xsl:for-each select="tokenize($times, ',\s*')">
              <xsl:variable name="time" select="."/>
              <iemployee time="{$time}">
                  <xsl:apply-templates select="$dep" mode="content"/>
              </iemployee>
          </xsl:for-each>
          </instances>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="department" mode="content">
           <xsl:apply-templates select="empname"/>
          <someelements></someelements>
          <xsl:apply-templates select="empno"/>
  </xsl:template>

答案 1 :(得分:1)

如果我理解你的问题,那么我认为你几乎就在那里:

<xsl:template match="department">
      <!-- Retain a reference to the current department element -->
      <xsl:variable name="dept" select="." as="node()"/>
      <xsl:copy>
          <xsl:copy-of select="@*"></xsl:copy-of>
          <xsl:apply-templates select="empname"/>
          <someelements></someelements>
          <xsl:apply-templates select="empno"/>
          <instances>
          <xsl:for-each select="tokenize($times, ',\s*')">
              <xsl:variable name="time" select="."/>
              <iemployee time="{$time}">
                  <!-- Apply templates to all children of the department node -->
                  <xsl:apply-templates select="$dept/*"/>
              </iemployee>
          </xsl:for-each>
          </instances>
      </xsl:copy>
  </xsl:template>