检查存在 - xslt 1.0中的多个键

时间:2014-05-28 04:11:49

标签: xslt xslt-1.0

所以我有这个xml

<BenefitDefinitions>
      <BenefitDefinition>
         <BenefitCode>A</BenefitCode>
         <FulfillmentName>Test</FulfillmentName>
      </BenefitDefinition>
      <BenefitDefinition>
         <BenefitCode>B</BenefitCode>
         <FulfillmentName>Test</FulfillmentName>
      </BenefitDefinition>
      <BenefitDefinition>
         <BenefitCode>C</BenefitCode>
         <FulfillmentName>Test</FulfillmentName>
      </BenefitDefinition>
    </BenefitDefinitions>
...
    <Risks>
      <ContractRisk>
        <RiskId>1</RiskId>
          <Coverage>
            <Cover>
               <BenefitCode>A</BenefitCode>
            <Cover>
          </Coverage>
      </ContractRisk>
      <ContractRisk>
        <RiskId>2</RiskId>
          <Coverage>
            <Cover>
               <BenefitCode>A</BenefitCode>
            <Cover>
          </Coverage>
      </ContractRisk>
     </Risks>

我需要在这里基本上应用转换:

For each risk 
  For each benefit definition group (where a group has the same fulfillmentName)
    If the benefit group has a cover associated to it (matched on benefitCode) 
          display the cover details
    Otherwise 
         display not covered details

坚持使用xslt 1.0,但我没有完全理解密钥的概念以及如何过滤密钥..所以我知道如果我没有风险,我可以使用这样的东西:

<xsl:key name="benefits-by-fulfillmentname" match="BenefitDefinition" use="FulfillmentName/text()" />
  <xsl:key name="cover-by-benefitcode" match="Cover" use="BenefitCode" />

  <!-- TODO: Make BonusSumInsured read from correct extract data when available -->
  <xsl:template name="PolicyScheduleBenefits">
    <xsl:param name="riskId" select="../../RiskId"/>

      <xsl:for-each select="//BenefitDefinition[count(. | key('benefits-by-fulfillmentname', FulfillmentName/text())[1]) = 1]">

        <group name="{FulfillmentName}">
          <xsl:choose>
            <xsl:when test="key('cover-by-benefitcode', key('benefits-by-fulfillmentname', FulfillmentName)/BenefitCode)">
              <xsl:text>there is a cover</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>there is not</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </group>

但我不确定如何调整这个以检查每个风险的保险是否存在。

2 个答案:

答案 0 :(得分:1)

我认为问题在于你是否有好处&#39;密钥查找&#39;覆盖&#39;对于所有风险,但您只想检查它是否存在特定风险。

要解决此问题,只需添加条件以检查当前使用密钥后的风险,如下所示:

<xsl:when test="key('cover-by-benefitcode', key('benefits-by-fulfillmentname', FulfillmentName)/BenefitCode)
                [../../RiskId =$riskId]">

答案 1 :(得分:1)

我相信我会这样做:假设这是XML输入的代表性示例:

<root>
   <BenefitDefinitions>
      <BenefitDefinition>
         <BenefitCode>A</BenefitCode>
         <FulfillmentName>group ABC</FulfillmentName>
      </BenefitDefinition>
      <BenefitDefinition>
         <BenefitCode>B</BenefitCode>
         <FulfillmentName>group ABC</FulfillmentName>
      </BenefitDefinition>
      <BenefitDefinition>
         <BenefitCode>C</BenefitCode>
         <FulfillmentName>group ABC</FulfillmentName>
      </BenefitDefinition>
      <BenefitDefinition>
         <BenefitCode>B</BenefitCode>
         <FulfillmentName>group BD</FulfillmentName>
      </BenefitDefinition>
      <BenefitDefinition>
         <BenefitCode>D</BenefitCode>
         <FulfillmentName>group BD</FulfillmentName>
      </BenefitDefinition>
   </BenefitDefinitions>
   <Risks>
      <ContractRisk>
         <RiskId>BC</RiskId>
         <Coverage>
            <Cover>
               <BenefitCode>B</BenefitCode>
            </Cover>
            <Cover>
               <BenefitCode>C</BenefitCode>
            </Cover>
         </Coverage>
      </ContractRisk>
      <ContractRisk>
         <RiskId>D</RiskId>
         <Coverage>
            <Cover>
               <BenefitCode>D</BenefitCode>
            </Cover>
         </Coverage>
      </ContractRisk>
   </Risks>
</root>

然后这个样式表:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="benefits-by-fulfillmentname" match="BenefitDefinition" use="FulfillmentName" />

<xsl:template match="/">
    <risks>
        <xsl:for-each select="root/Risks/ContractRisk">
            <risk id="{RiskId}">
            <xsl:variable name="riskCodes" select="Coverage/Cover/BenefitCode" />
                <xsl:for-each select="/root/BenefitDefinitions/BenefitDefinition[count(. | key('benefits-by-fulfillmentname', FulfillmentName)[1]) = 1]">
                    <group name="{FulfillmentName}">
                        <xsl:choose>
                            <xsl:when test="key('benefits-by-fulfillmentname', FulfillmentName)/BenefitCode=$riskCodes">
                                <xsl:text>there is a cover</xsl:text>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:text>there is not</xsl:text>
                            </xsl:otherwise>
                        </xsl:choose>
                    </group>
                </xsl:for-each>
            </risk>
        </xsl:for-each>
    </risks> 
</xsl:template> 

</xsl:stylesheet>

将产生以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<risks>
   <risk id="BC">
      <group name="group ABC">there is a cover</group>
      <group name="group BD">there is a cover</group>
   </risk>
   <risk id="D">
      <group name="group ABC">there is not</group>
      <group name="group BD">there is a cover</group>
   </risk>
</risks>

-
注意:与previous question不同,这不再是&#34;存在测试&#34;,而是节点集比较。