使用模板名称的变量调用命名模板

时间:2015-02-20 21:09:59

标签: templates xslt

我的问题是根据Tom Winter在以下帖子中的回答(https://stackoverflow.com/a/17728489/3574368):How to call named templates based on a variable? 我无法在原帖中添加评论,并发布了跟进问题。

我试图使用答案中描述的相同方法调用命名模板,但未成功。

基本XML来自格式为(摘录)的外部源:

<DRU1>
...
</DRU1>
<SIG1>
...
</SIG1>
<SIG2>
...
</SIG2>
...
<SIG20>
...
</SIG20>

每个模板都存在一个模板,存储在单独的xslt文件中,名称为SIG1,SIG2等。

构建主模板以根据元素的存在调用这些其他模板。我没有包括整个事情,只是尝试通过命名变量调用模板的顶部。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns="http://www.ncpdp.org/schema/SCRIPT">

  <xsl:output method="xml" indent="yes"/>

  <!-- Call Template case -->
  <xsl:include href="./DRU1aXML.xslt" />
  <xsl:include href="./DRU2aXML.xslt" />
  <xsl:include href="./SIG1XML.xslt" />
  <xsl:include href="./SIG2XML.xslt" />
  <xsl:include href="./SIG3XML.xslt" />
  <xsl:include href="./SIG4XML.xslt" />
  <xsl:include href="./SIG5XML.xslt" />
  <xsl:include href="./SIG6XML.xslt" />
  <xsl:include href="./SIG7XML.xslt" />
  <xsl:include href="./SIG8XML.xslt" />
  <xsl:include href="./SIG9XML.xslt" />
  <xsl:include href="./SIG10XML.xslt" />

  <xsl:variable name="templates">
    <templates><SIG1/><SIG2/><SIG3/><SIG4/><SIG5/><SIG6/><SIG7/><SIG8/><SIG9/><SIG10/>
    </templates>
  </xsl:variable>

  <xsl:template name="DRUMAIN" match="*[(starts-with(.,'DRU') or starts-with(.,'SIG'))]">

    <xsl:choose>      <!-- Prescribed -->
      <xsl:when test="DRU1/DRU1_010/DRU1_010_01='P'">
        <MedicationPrescribed>
          <xsl:call-template name="DRU1a"/>

          <xsl:for-each select="/*/*[starts-with(name(), 'SIG')]">
            <xsl:variable name="template-name" select="concat('SIG', position())"/>
            <xsl:apply-templates select="msxsl:node-set($templates)/*/*[local-name() = $template-name]" mode="call-template" />
          </xsl:for-each>

          <!--<xsl:if test="SIG1/SIG1_010">
            <xsl:call-template name="SIG1"/>
          </xsl:if>-->
        </MedicationPrescribed>
      </xsl:when>
...

模板永远不会被调用,除非我通过名称明确地调用它(参见注释掉的部分)。是否真的有必要列出这20次,明确使用模板的名称(SIG1,SIG2等)?或者可以使用position()以这种方式调用模板来构建模板名称吗?

更新:按要求添加了SIG1模板

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns="http://www.ncpdp.org/schema/SCRIPT">

  <xsl:output method="xml" indent="yes"/>
  <xsl:template name="SIG1" match="SIG1">
    <StructuredSIG>
      <RepeatingSIG>
        <SigSequencePositionNumber>
          <xsl:value-of select="SIG1/SIG1_010/SIG1_010_01"/>
        </SigSequencePositionNumber>
        <MultipleSigModifier>
          <xsl:value-of select="SIG1/SIG1_010/SIG1_010_02"/>
        </MultipleSigModifier>
      </RepeatingSIG>

      <CodeSystem>
        <SNOMEDVersion>
          <xsl:value-of select="SIG1/SIG1_020/SIG1_020_01"/>
        </SNOMEDVersion>
        <FMTVersion>
          <xsl:value-of select="SIG1/SIG1_020/SIG1_020_02"/>
        </FMTVersion>
      </CodeSystem>

      <FreeText>
        <SigFreeTextStringIndicator>
          <xsl:value-of select="SIG1/SIG1_030/SIG1_030_01"/>
        </SigFreeTextStringIndicator>
        <SigFreeText>
          <xsl:value-of select="SIG1/SIG1_030/SIG1_030_02"/>
        </SigFreeText>
      </FreeText>

      <Dose>
        <DoseCompositeIndicator>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_01"/>
        </DoseCompositeIndicator>
        <DoseDeliveryMethodText>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_02"/>
        </DoseDeliveryMethodText>
        <DoseDeliveryMethodCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_03"/>
        </DoseDeliveryMethodCodeQualifier>
        <DoseDeliveryMethodCode>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_04"/>
        </DoseDeliveryMethodCode>
        <DoseDeliveryMethodModifierText>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_05"/>
        </DoseDeliveryMethodModifierText>
        <DoseDeliveryMethodModifierCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_06"/>
        </DoseDeliveryMethodModifierCodeQualifier>
        <DoseDeliveryMethodModifierCode>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_07"/>
        </DoseDeliveryMethodModifierCode>
        <DoseQuantity>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_08"/>
        </DoseQuantity>
        <DoseFormText>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_09"/>
        </DoseFormText>
        <DoseFormCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_10"/>
        </DoseFormCodeQualifier>
        <DoseFormCode>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_11"/>
        </DoseFormCode>
        <DoseRangeModifier>
          <xsl:value-of select="SIG1/SIG1_040/SIG1_040_12"/>
        </DoseRangeModifier>
      </Dose>

      <DoseCalculation>
        <DosingBasisNumericValue>
          <xsl:value-of select="SIG1/SIG1_050/SIG1_050_01"/>
        </DosingBasisNumericValue>
        <DosingBasisUnitofMeasureText>
          <xsl:value-of select="SIG1/SIG1_050/SIG1_050_02"/>
        </DosingBasisUnitofMeasureText>
        <DosingBasisUnitofMeasureCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_050/SIG1_050_03"/>
        </DosingBasisUnitofMeasureCodeQualifier>
        <DosingBasisUnitofMeasureCode>
          <xsl:value-of select="SIG1/SIG1_050/SIG1_050_04"/>
        </DosingBasisUnitofMeasureCode>
        <BodyMetricQualifier>
          <xsl:value-of select="SIG1/SIG1_050/SIG1_050_05"/>
        </BodyMetricQualifier>
        <BodyMetricValue>
          <xsl:value-of select="SIG1/SIG1_050/SIG1_050_06"/>
        </BodyMetricValue>
        <CalculatedDoseNumeric>
          <xsl:value-of select="SIG1/SIG1_050/SIG1_050_07"/>
        </CalculatedDoseNumeric>
        <CalculatedDoseUnitofMeasureText>
          <xsl:value-of select="SIG1/SIG1_050/SIG1_050_08"/>
        </CalculatedDoseUnitofMeasureText>
        <CalculatedDoseUnitofMeasureCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_050/SIG1_050_09"/>
        </CalculatedDoseUnitofMeasureCodeQualifier>
        <CalculatedDoseUnitofMeasureCode>
          <xsl:value-of select="SIG1/SIG1_050/SIG1_050_10"/>
        </CalculatedDoseUnitofMeasureCode>
        <DosingBasisRangeModifier>
          <xsl:value-of select="SIG1/SIG1_050/SIG1_050_11"/>
        </DosingBasisRangeModifier>
      </DoseCalculation>

      <Vehicle>
        <VehicleName>
          <xsl:value-of select="SIG1/SIG1_060/SIG1_060_01"/>
        </VehicleName>
        <VehicleNameCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_060/SIG1_060_02"/>
        </VehicleNameCodeQualifier>
        <VehicleNameCode>
          <xsl:value-of select="SIG1/SIG1_060/SIG1_060_03"/>
        </VehicleNameCode>
        <VehicleQuantity>
          <xsl:value-of select="SIG1/SIG1_060/SIG1_060_04"/>
        </VehicleQuantity>
        <VehicleUnitOfMeasureText>
          <xsl:value-of select="SIG1/SIG1_060/SIG1_060_05"/>
        </VehicleUnitOfMeasureText>
        <VehicleUnitOfMeasureCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_060/SIG1_060_06"/>
        </VehicleUnitOfMeasureCodeQualifier>
        <VehicleUnitOfMeasureCode>
          <xsl:value-of select="SIG1/SIG1_060/SIG1_060_07"/>
        </VehicleUnitOfMeasureCode>
        <MultipleVehicleModifier>
          <xsl:value-of select="SIG1/SIG1_060/SIG1_060_08"/>
        </MultipleVehicleModifier>
      </Vehicle>

      <RouteofAdministration>
        <RouteofAdministrationText>
          <xsl:value-of select="SIG1/SIG1_070/SIG1_070_01"/>
        </RouteofAdministrationText>
        <RouteofAdministrationCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_070/SIG1_070_02"/>
        </RouteofAdministrationCodeQualifier>
        <RouteofAdministrationCode>
          <xsl:value-of select="SIG1/SIG1_070/SIG1_070_03"/>
        </RouteofAdministrationCode>
        <MultipleRouteofAdministrationModifier>
          <xsl:value-of select="SIG1/SIG1_070/SIG1_070_04"/>
        </MultipleRouteofAdministrationModifier>
      </RouteofAdministration>

      <SiteofAdministration>
        <SiteofAdministrationText>
          <xsl:value-of select="SIG1/SIG1_080/SIG1_080_01"/>
        </SiteofAdministrationText>
        <SiteofAdministrationCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_080/SIG1_080_02"/>
        </SiteofAdministrationCodeQualifier>
        <SiteofAdministrationCode>
          <xsl:value-of select="SIG1/SIG1_080/SIG1_080_03"/>
        </SiteofAdministrationCode>
        <MultipleAdministrationTimingModifier>
          <xsl:value-of select="SIG1/SIG1_080/SIG1_080_04"/>
        </MultipleAdministrationTimingModifier>
      </SiteofAdministration>

      <Timing>
        <AdministrationTimingText>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_01"/>
        </AdministrationTimingText>
        <AdministrationTimingCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_02"/>
        </AdministrationTimingCodeQualifier>
        <AdministrationTimingCode>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_03"/>
        </AdministrationTimingCode>
        <MultipleAdministrationTimingModifier>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_04"/>
        </MultipleAdministrationTimingModifier>
        <RateofAdministration>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_05"/>
        </RateofAdministration>
        <RateUnitofMeasureText>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_06"/>
        </RateUnitofMeasureText>
        <RateUnitofMeasureCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_07"/>
        </RateUnitofMeasureCodeQualifier>
        <RateUnitofMeasureCode>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_08"/>
        </RateUnitofMeasureCode>
        <TimePeriodBasisText>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_09"/>
        </TimePeriodBasisText>
        <TimePeriodBasisCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_10"/>
        </TimePeriodBasisCodeQualifier>
        <TimePeriodBasisCode>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_11"/>
        </TimePeriodBasisCode>
        <FrequencyNumericValue>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_12"/>
        </FrequencyNumericValue>
        <FrequencyUnitsText>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_13"/>
        </FrequencyUnitsText>
        <FrequencyUnitsCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_14"/>
        </FrequencyUnitsCodeQualifier>
        <FrequencyUnitsCode>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_15"/>
        </FrequencyUnitsCode>
        <VariableFrequencyModifier>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_16"/>
        </VariableFrequencyModifier>
        <IntervalNumericValue>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_17"/>
        </IntervalNumericValue>
        <IntervalUnitsText>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_18"/>
        </IntervalUnitsText>
        <IntervalUnitsCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_19"/>
        </IntervalUnitsCodeQualifier>
        <IntervalUnitsCode>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_20"/>
        </IntervalUnitsCode>
        <VariableIntervalModifier>
          <xsl:value-of select="SIG1/SIG1_090/SIG1_090_21"/>
        </VariableIntervalModifier>
      </Timing>

      <Duration>
        <DurationNumericValue>
          <xsl:value-of select="SIG1/SIG1_100/SIG1_100_01"/>
        </DurationNumericValue>
        <DurationText>
          <xsl:value-of select="SIG1/SIG1_100/SIG1_100_02"/>
        </DurationText>
        <DurationTextCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_100/SIG1_100_03"/>
        </DurationTextCodeQualifier>
        <DurationTextCode>
          <xsl:value-of select="SIG1/SIG1_100/SIG1_100_04"/>
        </DurationTextCode>
      </Duration>

      <MaximumDoseRestriction>
        <MaximumDoseRestrictionNumericValue>
          <xsl:value-of select="SIG1/SIG1_110/SIG1_110_01"/>
        </MaximumDoseRestrictionNumericValue>
        <MaximumDoseRestrictionUnitsText>
          <xsl:value-of select="SIG1/SIG1_110/SIG1_110_02"/>
        </MaximumDoseRestrictionUnitsText>
        <MaximumDoseRestrictionCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_110/SIG1_110_03"/>
        </MaximumDoseRestrictionCodeQualifier>
        <MaximumDoseRestrictionUnitsCode>
          <xsl:value-of select="SIG1/SIG1_110/SIG1_110_04"/>
        </MaximumDoseRestrictionUnitsCode>
        <MaximumDoseRestrictionVariableNumericValue>
          <xsl:value-of select="SIG1/SIG1_110/SIG1_110_05"/>
        </MaximumDoseRestrictionVariableNumericValue>
        <MaximumDoseRestrictionVariableUnitsText>
          <xsl:value-of select="SIG1/SIG1_110/SIG1_110_06"/>
        </MaximumDoseRestrictionVariableUnitsText>
        <MaximumDoseRestrictionVariableUnitsCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_110/SIG1_110_07"/>
        </MaximumDoseRestrictionVariableUnitsCodeQualifier>
        <MaximumDoseRestrictionVariableUnitsCode>
          <xsl:value-of select="SIG1/SIG1_110/SIG1_110_08"/>
        </MaximumDoseRestrictionVariableUnitsCode>
        <MaximumDoseRestrictionVariableDurationModifier>
          <xsl:value-of select="SIG1/SIG1_110/SIG1_110_09"/>
        </MaximumDoseRestrictionVariableDurationModifier>
      </MaximumDoseRestriction>

      <Indication>
        <IndicationPrecursorText>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_01"/>
        </IndicationPrecursorText>
        <IndicationPrecursorCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_02"/>
        </IndicationPrecursorCodeQualifier>
        <IndicationPrecursorCode>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_03"/>
        </IndicationPrecursorCode>
        <IndicationText>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_04"/>
        </IndicationText>
        <IndicationTextCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_05"/>
        </IndicationTextCodeQualifier>
        <IndicationTextCode>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_06"/>
        </IndicationTextCode>
        <IndicationValueText>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_07"/>
        </IndicationValueText>
        <IndicationValueUnit>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_08"/>
        </IndicationValueUnit>
        <IndicationValueUnitofMeasureText>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_09"/>
        </IndicationValueUnitofMeasureText>
        <IndicationValueUnitofMeasureCodeQualifier>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_10"/>
        </IndicationValueUnitofMeasureCodeQualifier>
        <IndicationValueUnitofMeasureCode>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_11"/>
        </IndicationValueUnitofMeasureCode>
        <IndicationVariableModifier>
          <xsl:value-of select="SIG1/SIG1_120/SIG1_120_12"/>
        </IndicationVariableModifier>
      </Indication>

      <Stop>
        <StopIndicator>
          <xsl:value-of select="SIG1/SIG1_130/SIG1_130_01"/>
        </StopIndicator>
      </Stop>

    </StructuredSIG>

    </xsl:template>
</xsl:stylesheet>  

1 个答案:

答案 0 :(得分:1)

问题是不匹配的mode属性 - 您的SIG1模板没有mode,但apply-templates却有。在mode上使用apply-templates时,只有声明相同模式的模板规则才会被视为潜在匹配。

但正如Martin在评论中所建议的那样,由于您正在查看的节点名称与您要应用的模板名称之间存在直接关联,因此您可以使用普通{{ 1}}让模板匹配器负责选择正确的模板:

apply-templates

<MedicationPrescribed> <xsl:call-template name="DRU1a"/> <xsl:apply-templates select="/*/*[starts-with(name(), 'SIG')]"/> 元素将使用SIG1等等

触发模板