XSLT : I need to parse the xml with same element name with sequence of order to map in to another xml with different name

允我心安 提交于 2020-02-08 06:46:21

问题


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>


来源:https://stackoverflow.com/questions/12187361/xslt-i-need-to-parse-the-xml-with-same-element-name-with-sequence-of-order-to

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!