基于xslt中的属性值匹配节点

时间:2018-04-19 11:58:29

标签: xslt xslt-1.0 xslt-2.0

我有一个输入xml,就像这样

<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>
        <FeatureOptProduct>
            <Name>Spousal Highest Daily Lifetime Income v3 with Highest Annual Death Benefit</Name>
            <ProductCode>SHDI3HADB</ProductCode>
        </FeatureOptProduct>
        <FeatureOptProduct>
            <Name>Spousal Highest Daily Lifetime Income v3 with Highest Daily Death Benefit</Name>
            <ProductCode>SHDIHDDB</ProductCode>
        </FeatureOptProduct>
</FeatureProduct>
<CalculationResult>
  <CalcResults />
  <TempCalcValuesData>
    <ChangeType>1</ChangeType>
    <MaxOwnerIssueAge>79</MaxOwnerIssueAge>
    <MaxOwnerIssueAge_Vector>
      <Value index="1">999</Value>
      <Value index="2">79</Value>
      <Value index="3">79</Value>
      <Value index="4">999</Value>
      <Value index="5">79</Value>
      <Value index="6">79</Value>
    </MaxOwnerIssueAge_Vector>
    <SegmentCovType>RIPAMP</SegmentCovType>
    <SegmentCovType_Vector>
      <Value index="1">RIP</Value>
      <Value index="2">DCA</Value>
      <Value index="3">DCA</Value>
      <Value index="4">IV</Value>
      <Value index="5">RIPAMP</Value>
    </SegmentCovType_Vector>
    <MaxAnnuitantIssueAge>79</MaxAnnuitantIssueAge>
    <MaxAnnuitantIssueAge_Vector>
      <Value index="1">999</Value>
      <Value index="2">79</Value>
      <Value index="3">79</Value>
      <Value index="4">999</Value>
      <Value index="5">79</Value>
      <Value index="6">79</Value>
    </MaxAnnuitantIssueAge_Vector>
    <SegmentCovOption>SHDI3HADB</SegmentCovOption>
    <SegmentCovOption_Vector>
      <Value index="1">HDI3</Value>
      <Value index="2">HDI3HDDB</Value>
      <Value index="3">HDI3HADB</Value>
      <Value index="4">SHDI3</Value>
      <Value index="5">SHDI3HDDB</Value>
      <Value index="6">SHDI3HADB</Value>
    </SegmentCovOption_Vector>
    <FeatureConflict>SPB</FeatureConflict>
    <FeatureConflict_Vector>
      <Value index="1">SPB</Value>
      <Value index="2">AA</Value>
      <Value index="3">IV</Value>
      <Value index="4">DCA</Value>
      <Value index="5">SPB</Value>
    </FeatureConflict_Vector>
    <MinAnnuitantIssueAge>50</MinAnnuitantIssueAge>
    <MinAnnuitantIssueAge_Vector>
      <Value index="1">50</Value>
      <Value index="2">50</Value>
      <Value index="3">50</Value>
      <Value index="4">50</Value>
      <Value index="5">50</Value>
      <Value index="6">50</Value>
    </MinAnnuitantIssueAge_Vector>
    <MinOwnerIssueAge>50</MinOwnerIssueAge>
    <MinOwnerIssueAge_Vector>
      <Value index="1">50</Value>
      <Value index="2">50</Value>
      <Value index="3">50</Value>
      <Value index="4">50</Value>
      <Value index="5">50</Value>
      <Value index="6">50</Value>
    </MinOwnerIssueAge_Vector>
  </TempCalcValuesData>
  <TempCalcValuesData>
    <ChangeType>1</ChangeType>
  </TempCalcValuesData>
  <TempCalcValuesData>
    <ChangeType>1</ChangeType>
  </TempCalcValuesData>
  <TempCalcValuesData>
    <ChangeType>1</ChangeType>
  </TempCalcValuesData>
  <TempCalcValuesData>
    <ChangeType>1</ChangeType>
  </TempCalcValuesData>
  <TempCalcValuesData>
    <ChangeType>1</ChangeType>
  </TempCalcValuesData>
  <TempCalcValuesData>
    <ChangeType>1</ChangeType>
  </TempCalcValuesData>
</CalculationResult>
</xml>

我想将输出转换为类似的东西

<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>
            <MaxOwnerIssueAge>999<MaxOwnerIssueAge>
        </FeatureOptProduct>
        <FeatureOptProduct>
            <Name>Spousal Highest Daily Lifetime Income v3 with Highest Annual Death Benefit</Name>
            <ProductCode>SHDI3HADB</ProductCode>
            <MaxOwnerIssueAge>79<MaxOwnerIssueAge>
        </FeatureOptProduct>
        <FeatureOptProduct>
            <Name>Spousal Highest Daily Lifetime Income v3 with Highest Daily Death Benefit</Name>
            <ProductCode>SHDIHDDB</ProductCode>
            <MaxOwnerIssueAge>79<MaxOwnerIssueAge>
        </FeatureOptProduct>
</xml>

基本上我想根据MaxOwnerIssueAge_Vector和SegmentCovOption_Vector

下的索引值映射这些值

每当MaxOwnerIssueAge_Vector中的index属性= SegmentCovOption_Vector时,获取其中的节点值 示例SHDI3的索引值为4,MaxOwnerIssueAge_Vector中的节点值为79,索引值为4,并将其放在FeatureOptProduct下的位置。

到目前为止,我已编写此代码,但它没有返回值

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
      <xsl:for-each select ="//FeatureProduct/FeatureOptProduct">
        <MaxOwnerAge>
            <xsl:for-each select="//CalculationResult/TempCalcValuesData/MaxOwnerIssueAge_Vector">        
              <xsl:choose>
                <xsl:when test="//CalculationResult/TempCalcValuesData/SegmentCovOption_Vector/Value/@index = //CalculationResult/TempCalcValuesData/MaxOwnerIssueAge_Vector/Value/@index">
                  <xsl:value-of select="//CalculationResult/MaxOwnerIssueAge_Vector/Value"/>
                </xsl:when>
              </xsl:choose>
            </xsl:for-each>
        </MaxOwnerAge> 
      </xsl:for-each>      
    </xsl:template>
</xsl:stylesheet>

有人可以帮我解决这个问题或告诉我一些逻辑吗

1 个答案:

答案 0 :(得分:0)

我建议你使用xsl:key。首先要有一个像

这样的键
<xsl:key name="kSegment" match="SegmentCovOption_Vector/Value" use="."/>

这将用于匹配ProductCode节点与SegmentCovOption_Vector/Value节点的值。

第二个键如下:

<xsl:key name="kMaxAge" match="MaxOwnerIssueAge_Vector/Value" use="@index"/>

将使用index属性获取目标值。

在匹配FeatureOptProduct节点时,为:

<xsl:template match="FeatureOptProduct">
    <xsl:variable name="target_index">
        <xsl:value-of select="key('kSegment', ProductCode)/@index"/>
    </xsl:variable>
    <xsl:copy>
        <xsl:apply-templates/>
        <MaxOwnerIssueAge>
            <xsl:value-of select="key('kMaxAge', $target_index)/text()"/>
        </MaxOwnerIssueAge>
    </xsl:copy>
</xsl:template>

在变量target_index中,我存储了我们感兴趣的索引号。然后我们在另一个键(kMaxAge)中使用它来获取所需的节点值。

整个样式表如下:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

    <xsl:key name="kSegment" match="SegmentCovOption_Vector/Value" use="."/>

    <xsl:key name="kMaxAge" match="MaxOwnerIssueAge_Vector/Value" use="@index"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="CalculationResult"/>

    <xsl:template match="FeatureOptProduct">
        <xsl:variable name="target_index">
            <xsl:value-of select="key('kSegment', ProductCode)/@index"/>
        </xsl:variable>
        <xsl:copy>
            <xsl:apply-templates/>
            <MaxOwnerIssueAge>
                <xsl:value-of select="key('kMaxAge', $target_index)/text()"/>
            </MaxOwnerIssueAge>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

在行动here中查看。