可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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:
Use:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" /> <xsl:template match="//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>
Input:
<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>
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>
回答2:
Ugh. I just answered the exact duplicate to this question.
Since both of my XSLT 1.0 examples and my XSLT 2.0 example are covered by Dimitre's and Kirill's answers, I'll add my XSLT 3.0 answer...
XML Input
<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 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 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>
回答3:
This generic transformation allows separate (even in a different document or passed as external parameter) mapping between the strings elements and the corresponding element name that must be generated:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my" exclude-result-prefixes="my"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <my:mapping> <map key="1" value="PolicyNumber"/> <map key="2" value="CommissionFactorMultiplier"/> <map key="3" value="PremiumValue"/> <map key="4" value="SalesmanCommissionValue"/> <map key="5" value="ManagerCommissionValue"/> <map key="7" value="GL_COR"/> <map key="8" value="GL_OPO"/> </my:mapping> <xsl:variable name="vMaps" select="document('')/*/my:mapping/*"/> <xsl:template match="values"> <CalculationOutput> <xsl:apply-templates/> </CalculationOutput> </xsl:template> <xsl:template match="strings"> <xsl:if test="position()=$vMaps/@key"> <xsl:variable name="vPos" select="position()"/> <xsl:element name="{$vMaps[@key = $vPos]/@value}"> <xsl:value-of select="."/> </xsl:element> </xsl:if> </xsl:template> </xsl:stylesheet>
When this transformation is applied on the provided XML document:
<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>
the wanted, correct result is produced:
<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>
II. This solution can be made very efficient by using keys:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my" exclude-result-prefixes="my"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <my:mapping> <map key="1" value="PolicyNumber"/> <map key="2" value="CommissionFactorMultiplier"/> <map key="3" value="PremiumValue"/> <map key="4" value="SalesmanCommissionValue"/> <map key="5" value="ManagerCommissionValue"/> <map key="7" value="GL_COR"/> <map key="8" value="GL_OPO"/> </my:mapping> <xsl:variable name="vMaps" select="document('')/*/my:mapping/*"/> <xsl:key name="kValueByKey" match="@value" use="../@key"/> <xsl:template match="values"> <CalculationOutput> <xsl:apply-templates/> </CalculationOutput> </xsl:template> <xsl:template match="strings"> <xsl:if test="position()=$vMaps/@key"> <xsl:variable name="vPos" select="position()"/> <xsl:variable name="vCur" select="."/> <xsl:for-each select="$vMaps/.."> <xsl:element name="{key('kValueByKey', $vPos)}"> <xsl:value-of select="$vCur"/> </xsl:element> </xsl:for-each> </xsl:if> </xsl:template> </xsl:stylesheet>