XSLT : Parse with multiple same name

匿名 (未验证) 提交于 2019-12-03 01:00:01

问题:

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> 


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