XSLT:具有多个相同名称的Parse

时间:2012-08-29 23:14:42

标签: xml xslt xpath

由于下面的源XML值/字符串元素值必须替换为目标元素值,有些人可以帮我解决如何创建XSL以从源xml转换为目标xml .Please。

源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>

目标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>

3 个答案:

答案 0 :(得分:2)

使用:

<?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>

输入:

<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>

输出:

<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 :(得分:1)

唉。我刚回答the exact duplicate to this question

由于我的XSLT 1.0示例和我的XSLT 2.0示例都包含在Dimitre和Kirill的答案中,我将添加我的XSLT 3.0答案......

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>
            </profiles>
        </SubItem>
    </subItems>
</PricingResultsV6>

XSLT 3.0 (使用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输出

<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 :(得分:0)

此通用转换允许在必须生成的strings元素和相应的元素名称之间进行单独(即使在不同的文档中或作为外部参数传递)映射:

<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>

在提供的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>
            </profiles>
        </SubItem>
    </subItems>
</PricingResultsV6>

产生了想要的正确结果

<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。使用密钥:

可以使此解决方案非常高效
<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>