XSLT : I need to parse the xml with same element n

2019-08-27 03:20发布

As the below source XML Value/string element value has to be replace with target element value, Could some please help me out how to create the XSL to transform from source xml into target xml .Please. Source XML:

<PricingResultsV6>     
 <subItems>
 <SubItem>   
<profiles>
<ProfileValues>
<values> 
 <strings>800210</strings> 
 <strings>THC</strings> 
 <strings>10.0</strings> 
 <strings>20.0</strings> 
 <strings>30.0</strings> 
 <strings>40.0</strings> 
 <strings>550.0</strings> 
 <strings>640.0</strings> 
 </values>
</ProfileValues>
</rofiles>
</SubItem>
</subItems>
</PricingResultsV6>

Target XML :

<CalculationOutput>
            <PolicyNumber> 800210 </PolicyNumber>
            <CommissionFactorMultiplier> THC </CommissionFactorMultiplier>
            <PremiumValue>10.0</PremiumValue>
            <SalesmanCommissionValue>20.0</SalesmanCommissionValue>
            <ManagerCommissionValue>30.0</ManagerCommissionValue>
            <GL_COR> 550.0</GL_COR>
            <GL_OPO>640.0</GL_OPO>

</CalculationOutput>

标签: xml parsing xslt
1条回答
Root(大扎)
2楼-- · 2019-08-27 04:08

You could do something basic like this...

XML Input (well-formed)

<PricingResultsV6>
    <subItems>
        <SubItem>
            <profiles>
                <ProfileValues>
                    <values>
                        <strings>800210</strings>
                        <strings>THC</strings>
                        <strings>10.0</strings>
                        <strings>20.0</strings>
                        <strings>30.0</strings>
                        <strings>40.0</strings>
                        <strings>550.0</strings>
                        <strings>640.0</strings>
                    </values>
                </ProfileValues>
            </profiles>
        </SubItem>
    </subItems>
</PricingResultsV6>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/PricingResultsV6/subItems/SubItem/profiles/ProfileValues/values">
        <CalculationOutput>
            <PolicyNumber><xsl:value-of select="strings[1]"/></PolicyNumber>
            <CommissionFactorMultiplier><xsl:value-of select="strings[2]"/></CommissionFactorMultiplier>
            <PremiumValue><xsl:value-of select="strings[3]"/></PremiumValue>
            <SalesmanCommissionValue><xsl:value-of select="strings[4]"/></SalesmanCommissionValue>
            <ManagerCommissionValue><xsl:value-of select="strings[5]"/></ManagerCommissionValue>
            <GL_COR><xsl:value-of select="strings[7]"/></GL_COR>
            <GL_OPO><xsl:value-of select="strings[8]"/></GL_OPO>            
        </CalculationOutput>
    </xsl:template>

</xsl:stylesheet>

XML Output

<CalculationOutput>
   <PolicyNumber>800210</PolicyNumber>
   <CommissionFactorMultiplier>THC</CommissionFactorMultiplier>
   <PremiumValue>10.0</PremiumValue>
   <SalesmanCommissionValue>20.0</SalesmanCommissionValue>
   <ManagerCommissionValue>30.0</ManagerCommissionValue>
   <GL_COR>550.0</GL_COR>
   <GL_OPO>640.0</GL_OPO>
</CalculationOutput>

Actual mapping options. All of these produce the same output as above...

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:loc="local" exclude-result-prefixes="loc">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <loc:map>
        <entry pos="1">PolicyNumber</entry>
        <entry pos="2">CommissionFactorMultiplier</entry>
        <entry pos="3">PremiumValue</entry>
        <entry pos="4">SalesmanCommissionValue</entry>
        <entry pos="5">ManagerCommissionValue</entry>
        <entry pos="7">GL_COR</entry>
        <entry pos="8">GL_OPO</entry>
    </loc:map>

    <xsl:template match="ProfileValues">
        <CalculationOutput>
            <xsl:apply-templates select="values/strings"/>
        </CalculationOutput>
    </xsl:template>

    <xsl:template match="strings[position()=document('')/*/loc:map/entry/@pos]">
        <xsl:variable name="vPos" select="position()"/>
        <xsl:element name="{document('')/*/loc:map/entry[@pos=$vPos]}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:stylesheet>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="vMap">
        <entry pos="1">PolicyNumber</entry>
        <entry pos="2">CommissionFactorMultiplier</entry>
        <entry pos="3">PremiumValue</entry>
        <entry pos="4">SalesmanCommissionValue</entry>
        <entry pos="5">ManagerCommissionValue</entry>
        <entry pos="7">GL_COR</entry>
        <entry pos="8">GL_OPO</entry>       
    </xsl:variable>

    <xsl:template match="ProfileValues">
        <CalculationOutput>
            <xsl:apply-templates select="values/strings"/>
        </CalculationOutput>
    </xsl:template>

    <xsl:template match="strings[position()=$vMap/entry/@pos]">
        <xsl:variable name="vPos" select="position()"/>
        <xsl:element name="{$vMap/entry[@pos=$vPos]}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:stylesheet>

XSLT 3.0 (tested with Saxon-EE 9.4)

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    exclude-result-prefixes="map">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="vMap" select="map {
        1:='PolicyNumber',
        2:='CommissionFactorMultiplier',
        3:='PremiumValue',
        4:='SalesmanCommissionValue',
        5:='ManagerCommissionValue',
        7:='GL_COR',
        8:='GL_OPO',
        }"/>

    <xsl:template match="ProfileValues">
        <CalculationOutput>
            <xsl:apply-templates select="values/strings"/>
        </CalculationOutput>
    </xsl:template>

    <xsl:template match="strings[map:contains($vMap,position())]">      
        <xsl:element name="{map:get($vMap,position())}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:stylesheet>
查看更多
登录 后发表回答