XSLT:将模板应用于当前范围之外的元素

时间:2015-04-03 13:47:44

标签: xml templates xslt

<root>
   <warningsAndCautions>
     <warning id="w1">
        <warningAndCautionPara>This is Warning 1, to fix refer to: 
            <dmref><dmcode assyCode="0001" disassyCode"00" disassyCodeVariant="X"
                      infoCode="001" infoCodeVariant="A" itemLocationCode="A"
                      modelIdentCode="AA" subSubSystemCode="9" subSystemCode="0"
                      systemCode="00" systemDiffCode="A"/>
            .
        </warningAndCautionPara>
     </warning>
     <warning id="w2">
        <warningAndCautionPara>This is Warning 1, to fix refer to: 
           <dmref><dmcode assyCode="1111" disassyCode"11" disassyCodeVariant="X"
                      infoCode="111" infoCodeVariant="A" itemLocationCode="A"
                      modelIdentCode="AA" subSubSystemCode="9" subSystemCode="0"
                      systemCode="11" systemDiffCode="A"/>
        .
        </warningAndCautionPara>
     </warning>
   </warningsAndCautions>

   <content>
     <step warningRef="W1">
        <para>Step 1</para>
        <para>Description 1</para>
     </step>
     <step>
        <para>Step 2</para>
        <para>Description 2</para>
     </step>
   </content>
</root>

XSLT示例:

<xsl:template match="step">
   <xsl:variable name="warnRef">
      <xsl:value-of select="./@warningRef"/>
   </xsl:variable>

   <!-- If there is a warningRef attribute on the step, process the associated <warning> element -->
   <xsl:choose>
      <xsl:when test="not($warnRef='')">
      <!-- Need to somehow call the template to process the <warning> element with the id of w1 -->
      </xsl:when>
      <xsl:otherwise>

      </xsl:otherwise>
   </xsl:choose>
</xsl:template>

我想要获得的输出是这样的:

**WARNING:**  This is Warning 1, to fix refer to: 0001-00-X-001-A-A-AA-9-0-00-A .
Step 1
Description 1

Step 2
Description 2

我正在尝试弄清楚如何编写XSLT来生成上面的WARNING语句。当我处理<step>模板时,我需要检查是否存在warningRef属性。如果有,我需要处理id为<warning>的{​​{1}}元素。在处理元素时,我无法弄清楚如何为warningRef应用模板。由于它不是<warningAndCautionPara>的子元素,因此apply-template不起作用。正如您所看到的那样,它是混合内容,因此我需要确保同时处理<step>模板。

2 个答案:

答案 0 :(得分:2)

XSLT具有用于处理交叉引用的内置key机制。要使用它,首先要在样式表的顶层定义一个键:

<xsl:key name="warning" match="warning" use="@id" />

然后使用此键将模板应用于当前步骤中引用的警告,例如:

<xsl:template match="step">
    <xsl:apply-templates select="key('warning', @warningRef)"/>
    <!-- instructions for processing the step -->
</xsl:template>

<xsl:template match="warning">
    <!-- instructions for processing the warning -->
</xsl:template>

注意
XML区分大小写:warningRef="W1" 匹配<warning id="w1">

答案 1 :(得分:0)

您需要的电话如下:

<xsl:apply-templates select="//warning[@id=$warnRef]" />

注意:在上面的示例中,它可能无法正常工作,因为引用写为'W1'且id为'w1' - 请注意匹配大小写。