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

2019-08-27 03:45发布

问题:

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>

回答1:

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>


标签: xml parsing xslt