XSLT group if condition is matched

后端 未结 1 1940
孤街浪徒
孤街浪徒 2021-01-28 03:29

INPUT:

  


    


    
             


        
相关标签:
1条回答
  • 2021-01-28 03:56

    I think it is better to prevent duplicates in MSTP and MSONPC and put them into one template where input parameter will be non-duplicated VRPlanId as in XSL below:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
        <xsl:output method="xml" /> 
        <xsl:template name="task-attr">
            <!--parameter to filter per VRPlanId-->     
            <xsl:param name="param.VRPlanId"/>              
            <xsl:variable name="var.mstp">                      
                <xsl:for-each select="/output/meta2/tag/output_getquerydata/queries/query/queryResults/record[column[@name='VRPlanId'] = $param.VRPlanId]">
                    <!--preventing empty blocks and duplicates for MSTP-->          
                    <xsl:if test="string-length(column[@name='MSTP']) &gt;0 and not(preceding::record[column[@name='MSTP']/text() = current()/column[@name='MSTP']/text()])">                   
                        <xsl:value-of select="concat(column[@name='MSTP'], ',')"/>              
                    </xsl:if>                                       
                </xsl:for-each>                             
            </xsl:variable>     
            <xsl:variable name="var.msonpc">                        
                <xsl:for-each select="/output/meta2/tag/output_getquerydata/queries/query/queryResults/record[column[@name='VRPlanId'] = $param.VRPlanId]">
                    <!--preventing empty blocks and duplicates for MSONPC-->            
                    <xsl:if test="string-length(column[@name='MSONPC']) &gt;0 and not(preceding::record[column[@name='MSONPC']/text() = current()/column[@name='MSONPC']/text()])">                 
                        <xsl:value-of select="concat(column[@name='MSONPC'], ',')"/>                
                    </xsl:if>                                       
                </xsl:for-each>                             
            </xsl:variable>
            <!--concat all non-duplicates MSTP and MSONPC without last delimiter--> 
            <xsl:value-of select="concat($var.mstp, substring($var.msonpc, 1, string-length($var.msonpc)-1))"/>     
        </xsl:template>
    
        <xsl:template match="/">        
            <output>            
                <xsl:for-each select="/output/meta2/tag/output_getquerydata/queries/query/queryResults/record">             
                    <xsl:if test ="not(preceding::record[column[@name='VRPlanId']/text() = current()/column[@name='VRPlanId']/text()])">                    
                        <xsl:variable name="task.id">                                                   
                            <xsl:call-template name="task-attr">
                                <!--as input parameter put non-duplicate VRPlanId-->                                                            
                                <xsl:with-param name="param.VRPlanId" select="column[@name='VRPlanId']"/>                                                   
                            </xsl:call-template>                                    
                        </xsl:variable>
                        <!--if all non-duplicates MSTP and MSONPC will be blank block Cdo won't be created-->                   
                        <xsl:if test="string-length($task.id) &gt;0">                       
                            <Cdo>                           
                                <parameters>                                
                                    <task>                                                          
                                        <xsl:attribute name="id">                                                       
                                            <xsl:value-of select="$task.id"/>               
                                        </xsl:attribute>                                
                                    </task>                             
                                    <action>                                                            
                                        <xsl:attribute name="id">                                                                           
                                            <xsl:value-of select="column[@name='VRPlanId']"/>                                                               
                                        </xsl:attribute>                                
                                    </action>                                           
                                </parameters>                       
                            </Cdo>                                      
                        </xsl:if>               
                    </xsl:if>           
                </xsl:for-each>                     
            </output>   
        </xsl:template>
    </xsl:stylesheet>
    

    You have edited your version of XML but in case of XML below:

    <?xml version="1.0" encoding="UTF-8"?>
    <output>
    <input>
        <!--details-->
    </input>
    <meta2>
        <tag>
            <output_getquerydata>
                <queries>
                    <query name="part1">
                        <parameters>
                            <!--details-->
                        </parameters>
                        <queryErrors>
                            <!--details-->
                        </queryErrors>
                        <queryResults>
                            <record id="1">                              
                                <column name="VRIdTask">1</column>                               
                                <column name="MSTP">22</column>
                                <column name="VRPlanId">11310224</column>                                
                                <column name="MSONPC">221</column> 
                            </record>
                            <record id="2">
                                <column name="VRIdTask">1</column>
                                <column name="MSTP">22</column>
                                <column name="VRPlanId">11310224</column> 
                                <column name="MSONPC">2211</column> 
                            </record>
                            <record id="3"> 
                                <column name="VRIdTask">3</column> 
                                <column name="MSTP"/>
                                <column name="VRPlanId">11310337</column> 
                                <column name="MSONPC"/> 
                            </record>
                            <record id="4"> 
                                <column name="VRIdTask">2</column> 
                                <column name="MSTP"/>
                                <column name="VRPlanId">11310281</column> 
                                <column name="MSONPC">2221</column> 
                            </record>
                            <record id="5"> 
                                <column name="VRIdTask">4</column> 
                                <column name="MSTP">33</column>
                                <column name="VRPlanId">11310281</column> 
                                <column name="MSONPC">222221</column> 
                            </record>
                            <record id="6"> 
                                <column name="VRIdTask">4</column> 
                                <column name="MSTP">331</column>
                                <column name="VRPlanId">11310281</column> 
                                <column name="MSONPC">222221</column> 
                            </record>
                        </queryResults>
                    </query>
                </queries>
            </output_getquerydata>
        </tag>
    </meta2>
    </output>
    

    The result is:

    <?xml version="1.0" encoding="UTF-8"?>
    <output>
        <Cdo>
            <parameters>
                <task id="22,221,2211"/>
                <action id="11310224"/>
            </parameters>
        </Cdo>
        <Cdo>
            <parameters>
                <task id="33,331,2221,222221"/>
                <action id="11310281"/>
            </parameters>
        </Cdo>
    </output>
    

    NOTE! In proposed XSL there is validation for empty values, if you will require include them just remove that validations.

    In case when it is required to use each attribute value in separate task tag then you can create task blocks structure in separate template and call it in parameters block as below:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
        <xsl:output method="xml" /> 
        <xsl:template name="task-attr">
            <!--parameter to filter per VRPlanId-->     
            <xsl:param name="param.VRPlanId"/>
            <tasks>
                <xsl:for-each select="/output/meta2/tag/output_getquerydata/queries/query/queryResults/record[column[@name='VRPlanId'] = $param.VRPlanId]">
                    <!--preventing empty blocks and duplicates for MSTP-->          
                    <xsl:if test="string-length(column[@name='MSTP']) &gt;0 and not(preceding::record[column[@name='MSTP']/text() = current()/column[@name='MSTP']/text()])">
                        <task>
                            <xsl:attribute name="id">
                                <xsl:value-of select="column[@name='MSTP']"/>
                            </xsl:attribute>
                        </task>                                                   
                    </xsl:if>                                       
                </xsl:for-each>
                <xsl:for-each select="/output/meta2/tag/output_getquerydata/queries/query/queryResults/record[column[@name='VRPlanId'] = $param.VRPlanId]">
                    <!--preventing empty blocks and duplicates for MSONPC-->            
                    <xsl:if test="string-length(column[@name='MSONPC']) &gt;0 and not(preceding::record[column[@name='MSONPC']/text() = current()/column[@name='MSONPC']/text()])">
                        <task>
                            <xsl:attribute name="id">                                                     
                                <xsl:value-of select="column[@name='MSONPC']"/>
                            </xsl:attribute>
                        </task>                
                    </xsl:if>                                       
                </xsl:for-each>            
            </tasks>                                                   
        </xsl:template>
    
        <xsl:template match="/">        
            <output>            
                <xsl:for-each select="/output/meta2/tag/output_getquerydata/queries/query/queryResults/record">             
                    <xsl:if test ="not(preceding::record[column[@name='VRPlanId']/text() = current()/column[@name='VRPlanId']/text()])"> 
                            <Cdo>                           
                                <parameters>                                                        
                                    <xsl:call-template name="task-attr">                                                                                                                   
                                        <xsl:with-param name="param.VRPlanId" select="column[@name='VRPlanId']"/>                                                                           
                                    </xsl:call-template>                                                             
                                    <action>                                                            
                                        <xsl:attribute name="id">                                                                           
                                            <xsl:value-of select="column[@name='VRPlanId']"/>                                                               
                                        </xsl:attribute>                                
                                    </action>                                           
                                </parameters>                       
                            </Cdo>                                                                                                                  
                    </xsl:if>           
                </xsl:for-each>                     
            </output>   
        </xsl:template>
    </xsl:stylesheet>
    

    Then when you will check it with XML above the result will be as below:

    <?xml version="1.0" encoding="UTF-8"?>
    <output>
        <Cdo>
            <parameters>
                <tasks>
                    <task id="22"/>
                    <task id="221"/>
                    <task id="2211"/>
                </tasks>
                <action id="11310224"/>
            </parameters>
        </Cdo>
        <Cdo>
            <parameters>
                <tasks/>
                <action id="11310337"/>
            </parameters>
        </Cdo>
        <Cdo>
            <parameters>
                <tasks>
                    <task id="33"/>
                    <task id="331"/>
                    <task id="2221"/>
                    <task id="222221"/>
                </tasks>
                <action id="11310281"/>
            </parameters>
        </Cdo>
    </output>
    

    Of course you can add blank values validation where it is required.

    Hope it will help with your case.

    0 讨论(0)
提交回复
热议问题