问题
So I'm stuck with XSLT 1.0
In my XML I have something like this:
<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>
...
<Coverage>
<Cover>
<BenefitCode>A</BenefitCode>
<Cover>
</Coverage>
The logic needs to be where there are multiple benefit Definitions that have that same fulfillmentName - I need to check if any of them exist as a cover. With the linkage between the two being the BenefitCode.
I tried using a key to get the benefitDefinitions into groups based on the fulfillment name
<xsl:key name="benefits-by-fulfillmentname" match="BenefitDefinition" use="FulfillmentName/text()" />
and I can iterate through the groups where there is more than 1
<xsl:for-each select="//BenefitDefinition[count(. | key('benefits-by-fulfillmentname', FulfillmentName/text())[1]) = 1]">
I could also iterate through the benefitDefinitions of that group by:
<xsl:for-each select="key('benefits-by-fulfillmentname', FulfillmentName/text())">
But what I can't figure out is how I can make use of the key to get a count.
I want something like this:
<xsl:value-of select="count(../../../../Contract/Risks/PersonContractRisk[RiskId = $riskId]/Coverage/Cover[BenefitCode=key('benefits-by-fulfillmentname', BenefitCode)])"/>
But that's not working - I'm not skilled with xslt so not too surprising.
All my searching just tells me how to count the benefitDefinitions that belong in that group.. but I need to go more advanced and find out how many covers exist for that benefitDefinition group.
Pretty much where I want to go to (in case this helps) is for each benefitDefinition group if there is a cover output 1 thing, otherwise output something else.
回答1:
You don't need to count or iterate; a simple existence test will suffice.
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:key name="cover-by-benefitcode" match="Cover" use="BenefitCode" />
<xsl:template match="/">
<output>
<xsl:for-each select="root/BenefitDefinitions/BenefitDefinition[count(. | key('benefits-by-fulfillmentname', FulfillmentName)[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>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
When this is applied to the following valid XML test input:
<root>
<BenefitDefinitions>
<BenefitDefinition>
<BenefitCode>A</BenefitCode>
<FulfillmentName>group A</FulfillmentName>
</BenefitDefinition>
<BenefitDefinition>
<BenefitCode>B</BenefitCode>
<FulfillmentName>group A</FulfillmentName>
</BenefitDefinition>
<BenefitDefinition>
<BenefitCode>C</BenefitCode>
<FulfillmentName>group A</FulfillmentName>
</BenefitDefinition>
<BenefitDefinition>
<BenefitCode>C</BenefitCode>
<FulfillmentName>group B</FulfillmentName>
</BenefitDefinition>
</BenefitDefinitions>
<Coverage>
<Cover>
<BenefitCode>B</BenefitCode>
</Cover>
</Coverage>
</root>
the result will be:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<group name="group A">there is a cover</group>
<group name="group B">there is not</group>
</output>
来源:https://stackoverflow.com/questions/23863664/struggling-with-xslt-grouping-and-querying-against-xpath-count