如何在XSLT中基于属性值匹配节点?附输入XML示例
First, let's assume your full XML looks something like this (filling in the truncated section for context):
<xml> <FeatureProduct> <Name>Spousal Guaranteed Lifetime Withdrawal Benefit</Name> <FeatureCode>SPB</FeatureCode> <FeatureOptConflict> <!-- Exclusive Benefits --> <FeatureCode>RIP</FeatureCode> </FeatureOptConflict> <FeatureOptProduct> <Name>Spousal Highest Daily Lifetime Income v3</Name> <ProductCode>SHDI3</ProductCode> </FeatureOptProduct> </FeatureProduct> </xml>
Below are practical, actionable solutions to match nodes based on their values (like FeatureCode or ProductCode) in XSLT:
1. Match a Parent Node by Child Element Value
If you want to target the entire <FeatureProduct> node where its <FeatureCode> equals SPB, use a template match with an XPath predicate to filter:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- Match FeatureProduct with FeatureCode = 'SPB' --> <xsl:template match="FeatureProduct[FeatureCode='SPB']"> <SelectedBenefit> <BenefitName><xsl:value-of select="Name"/></BenefitName> <ExclusiveBenefit> <!-- Pull the conflicting FeatureCode from the nested section --> <xsl:value-of select="FeatureOptConflict/FeatureCode"/> </ExclusiveBenefit> <LinkedProduct> <xsl:value-of select="FeatureOptProduct/Name"/> <xsl:text> (Code: </xsl:text> <xsl:value-of select="FeatureOptProduct/ProductCode"/> <xsl:text>)</xsl:text> </LinkedProduct> </SelectedBenefit> </xsl:template> <!-- Default template to skip unmatched nodes/text --> <xsl:template match="text()|@*"/> </xsl:stylesheet>
2. Directly Match Child Nodes by Value
If you only need to target specific child nodes (e.g., the conflicting <FeatureCode> with value RIP), write a template for that exact node:
<xsl:template match="FeatureOptConflict/FeatureCode[.='RIP']"> <ConflictWarning> <xsl:text>Benefit </xsl:text> <xsl:value-of select="."/> <xsl:text> cannot be combined with </xsl:text> <xsl:value-of select="../../FeatureCode"/> </ConflictWarning> </xsl:template>
3. Parameterized Matching (For Reusable Logic)
If you need to match dynamic values (e.g., a product code passed in at runtime), use parameters to make your templates flexible:
<xsl:param name="targetProductCode" select="'SHDI3'"/> <xsl:template match="FeatureOptProduct[ProductCode=$targetProductCode]"> <MatchedProduct> <ProductName><xsl:value-of select="Name"/></ProductName> <ProductCode><xsl:value-of select="ProductCode"/></ProductCode> </MatchedProduct> </xsl:template>
Sample Output (From the First XSLT)
When you run the first stylesheet against your XML, you'll get:
<SelectedBenefit> <BenefitName>Spousal Guaranteed Lifetime Withdrawal Benefit</BenefitName> <ExclusiveBenefit>RIP</ExclusiveBenefit> <LinkedProduct>Spousal Highest Daily Lifetime Income v3 (Code: SHDI3)</LinkedProduct> </SelectedBenefit>
Quick tips to remember:
- Use XPath predicates (
[element='value']) to filter nodes based on child values - Traverse the XML tree with relative paths (e.g.,
../../FeatureCodeto move up two levels) - Parameters let you reuse matching logic for different input values
内容的提问来源于stack exchange,提问作者Hitzz91

