如何通过XSL使用密钥调用模板

时间:2013-04-11 21:24:29

标签: xml xslt

我几乎解决了这个问题,然后发现coverage-ref是相应coverage元素中的一个关键属性。

Xpath看起来像

/消息/人-方式/权利要求列表/权利要求/

<coverage-ref>4</coverage-ref>

/消息/人-方式/覆盖列表/

<coverage key="4" id="23" >
...
</coverage>

当前XSL的片段

<xsl:template match="claim" mode="fact">
    <ClaimFact>
        <coverage>
                <xsl:choose>
                    <xsl:when test="./coverage-ref">
                    <!-- 
                    COVERAGE-<xsl:value-of select="util:ifNull(./coverage-ref, '0')"/>
                    -->
                        <xsl:call-template name="coverage-ref">
                            <xsl:with-param name="coverage-ref" select="./coverage-ref" />
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:when test="./../../../coverage/@id">COVERAGE-<xsl:value-of select="./../../../coverage/@id"/></xsl:when>                       
                    <xsl:otherwise><xsl:text>UNKNOWNCOVERAGE</xsl:text></xsl:otherwise>
                </xsl:choose>
        </coverage>     
    </ClaimFact>
</xsl:template> 

<xsl:template match="coverage|coverage-ref" >
<xsl:param name="coverage-ref" />
<xsl:variable name="coverage" 
        select="/person-info/coverage-list/coverage[@key = $coverage-ref]" />   
    <CoverageDimension>
        <mycoverageref><xsl:value-of select="$coverage" /></mycoverageref>
...

    </CoverageDimension>
</xsl:template>

我得到的错误

Error at xsl:call-template on line 1845 column 51 of personinfo.xsl:
  XTSE0650: No template exists named coverage-ref

现有注释将把coverage-ref放入mycoverageref。

我试图用xsl:call-template,xsl:param和xsl:variable来做1)将mycoverageref设置为元素的@id而不是@key。

2)最好将值4替换为23,然后现有的apply-templates应该适用于CoverageDimension。

提前致谢!

2 个答案:

答案 0 :(得分:2)

您正在尝试调用命名模板“template-ref”

<xsl:call-template name="coverage-ref">
   <xsl:with-param name="coverage-ref" select="./coverage-ref" />
</xsl:call-template>

但是你的XSLT中没有这样的模板。您只有一个与 coverage-ref 元素匹配的模板

<xsl:template match="coverage|coverage-ref">

这与命名模板不同。

你有可能这样做......

<xsl:template match="coverage" name="coverage-ref">

这将是匹配模板和命名模板。或者,您可以将原始 xsl:call-template 更改为 xsl:apply-templates 此处

<xsl:apply-template select="coverage-ref">
    <xsl:with-param name="coverage-ref" select="./coverage-ref" />
</xsl:apply-templates>

你真的不需要传递参数。匹配模板可以直接获取元素的值。

<xsl:template match="coverage-ref" >
    <xsl:variable name="coverage" select="/person-info/coverage-list/coverage[@key = .]" />  

但无论如何,你谈的是'钥匙',但你实际上并没有使用'正确'钥匙。特别是 xsl:key 。这就是在这种情况下你需要的东西。您想通过属性查找 coverage 元素吗?然后只需定义一个像这样的键

<xsl:key name="coverageLookup" match="coverage" use="@key" />

然后要查找coverage元素,只需执行以下操作:

<xsl:value-of select="key('coverageLookup', $coverage-ref)/@id" />

或者,如果您使用匹配的模板,它将看起来像这样

<xsl:template match="coverage-ref" >
   <CoverageDimension>
      <mycoverageref><xsl:value-of select="key('coverageLookup', .)/@id" /></mycoverageref>
      ...
   </CoverageDimension>
</xsl:template>

答案 1 :(得分:0)

这是我做的,非常感谢@ Tim-C。我们将不得不考虑未来版本的keyLookup,但这适用于当前的xml。使用变量$coverpathcoverage/@keycoverage-ref/text()值相匹配,可以实现此功能。

<xsl:stylesheet version="20" 
...
<xsl:template match="person-info">
    <PersonDimension>
    ...
    </PersonDimension>
    <xsl:apply-templates select="coverage-list/coverage" />         
    <xsl:apply-templates select="//claim-list/claim" mode="fact" />
</xsl:template>

<xsl:template match="claim" mode="fact">
    <xsl:variable name="coveragepath" 
        select="/message/person-info/coverage-list/coverage[@key = current()/coverage-ref/text()]" />

    <ClaimFact>
...
        <coverage>
                <xsl:choose>
                    <xsl:when test="$coveragepath/@id">                     
                        COVERAGE-<xsl:value-of select="$coveragepath/@id"/>
                    </xsl:when>
                    <xsl:when test="./../../../coverage/@id">COVERAGE-<xsl:value-of select="./../../../coverage/@id"/></xsl:when>                       
                    <xsl:otherwise>UNKNOWNCOVERAGE</xsl:otherwise>
                </xsl:choose>
        </coverage> 
    </ClaimFact>

</xsl:template> 

<xsl:template match="coverage" >
<CoverageDimension>
        <jaxbId>
        <xsl:choose>
            <xsl:when test="@id">COVERAGE-<xsl:value-of select="@id"/></xsl:when>
            <xsl:otherwise>UNKNOWNCOVERAGE</xsl:otherwise>
        </xsl:choose>
        </jaxbId>
    </CoverageDimension>
</xsl:template>