【问题标题】:how to call a template using an key via XSL如何通过 XSL 使用键调用模板
【发布时间】:2013-04-11 21:24:29
【问题描述】:

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

Xpath 看起来像

/message/person-info/claim-list/claim/

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

/message/person-info/coverage-list/

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

当前 XSL 的 sn-p

<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,然后现有的应用模板应该适用于 CoverageDimension。

提前致谢!

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    您正在尝试调用命名模板“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。这正是您在这种情况下所需要的。您想通过 key 属性查找 coverage 元素吗?然后像这样定义一个键

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

    然后查找覆盖元素,只需这样做:

    <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>
    

    【讨论】:

    • 我使用了您的部分解决方案,并将在答案中发布我所做的。当前的 xsl 没有定义任何键或键查找。我们可能希望在未来的版本中采用这条路线,但这需要对现有 xsl 进行全面重写。
    【解决方案2】:

    这就是我所做的,非常感谢@Tim-C。我们将不得不考虑未来版本的 keyLookups,但这适用于当前的 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-20
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-16
      • 1970-01-01
      相关资源
      最近更新 更多