XML - XSLT - 使用辅助文档和 <xsl:next-match>

XML - XSLT - Working with auxiliar document and <xsl:next-match>

我有以下 XML 输入文档:

<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://jasperreports.sourceforge.net/jasperreports" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" 
        repName="FirstElementTemp" 
        date="10-05-2001">
    <element1>
        <subElement>
            SomeData
        </subElement>
    </element1>
    <element2>
        <subElement type="2"/>
    </element2>
</report>

我想在 <element1> 元素之前添加一个名为 <valueIs> 的新元素,数据来自我用作 [=18] 的第二个 XML 输入文件=]

所以基本上这是我想要得到的输出:

<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://jasperreports.sourceforge.net/jasperreports"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
        repName="FirstElementTemp"
        date="10-05-2001">
      <valueIs>FIRST DATA</valueIs>
      <element1>
        <subElement>
            SomeData
        </subElement>
      </element1>
      <element2>
            <subElement type="2"/>
      </element2>
</report>

这是我正在使用的 XSLT 代码(第二个 XML 内联文档,作为 ):

<?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"
  xpath-default-namespace="http://jasperreports.sourceforge.net/jasperreports"
  xmlns:jsp="http://jasperreports.sourceforge.net/jasperreports"
  exclude-result-prefixes="xs jsp"
  expand-text="yes"
  version="3.0">


<xsl:param name="doc2"  xmlns="">
    <secondDoc>
    <elementTemps>
        <elemTemp ID="1" name="FirstElementTemp" />
        <elemTemp ID="2" name="SecondTemplate" />
    </elementTemps>
    <elementReps>
        <elemRep tmpID="1" name="FirstElementRep" >
            <value>FIRST DATA</value>
        </elemRep>
        <elemRep tmpID="2" name="SecondTemplate">
            <value>SECOND DATA</value>
        </elemRep>
    </elementReps>
    </secondDoc>     
  </xsl:param>

<xsl:output indent="yes" cdata-section-elements="cDataElement"/>

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

  <xsl:key name="key1" match="elemTemp" use="@name" xpath-default-namespace=""/>
  <xsl:key name="key2" match="elemRep" use="@tmpID" xpath-default-namespace=""/>

  <xsl:template match="report">
      <xsl:next-match/>
      <xsl:variable name="temp" select="key('key1', @repName, $doc2)"/>
      <xsl:variable name="rep" select="key('key2', $temp/@ID, $doc2)"/>

      <valueIs>
          <xsl:value-of select="$rep/value" xpath-default-namespace=""/>
      </valueIs>

  </xsl:template>

</xsl:stylesheet>

产生以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://jasperreports.sourceforge.net/jasperreports"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
        repName="FirstElementTemp"
        date="10-05-2001">
      <element1>
        <subElement>
            SomeData
        </subElement>
      </element1>
      <element2>
            <subElement type="2"/>
      </element2>
</report>
<valueIs>FIRST DATA</valueIs>

我知道我不能在那里使用 <xsl:next-match>,但问题是我需要 <report> 元素作为当前节点,因为 keys 我是使用,

有什么方法可以在 <element1> 文件之前专门创建 <valueIs> 文件吗?我需要将 <valueIs> 元素保留在 <report> 元素内,因为该元素是根节点...

谢谢!

亚历山大·哈辛托

与其依赖 <xsl:next-match> 执行所有工作,不如将一些 identity-template 逻辑放入您的模板以复制元素,将模板应用到它的属性,插入您的自定义内容,然后将模板应用于子节点:

<xsl:template match="report">
    <xsl:variable name="temp" select="key('key1', @repName, $doc2)"/>
    <xsl:variable name="rep" select="key('key2', $temp/@ID, $doc2)"/>
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <valueIs>
            <xsl:value-of select="$rep/value" xpath-default-namespace=""/>
        </valueIs>
        <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

或者,您可以更改模板以匹配第一个子元素:report/*[1],然后在 select 从 key1 跳转到 report 元素到 select 是 @repName,生成新元素然后使用 xsl:next-match.

<xsl:template match="report/*[1]">
    <xsl:variable name="temp" select="key('key1', ../@repName, $doc2)"/>
    <xsl:variable name="rep" select="key('key2', $temp/@ID, $doc2)"/>
    <valueIs>
        <xsl:value-of select="$rep/value" xpath-default-namespace=""/>
    </valueIs>
    <xsl:next-match/>
</xsl:template>