如果条件匹配,则为XSLT组

时间:2017-12-12 03:27:53

标签: xml xslt key xslt-grouping

INPUT:

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

XSL:

      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="k" match="output/meta2/tag/output_getquerydata/queries/query/queryResults/record" use="./column[@name='VRPlanId']"/>
<xsl:template match="@*|node()">
    <xsl:variable name="distinctOrder" select="//record[string(column[@name='VRPlanId'])][count(. | key('k', column[@name='VRPlanId'])[1]) >1]"/>
    <xsl:if test="count(key('k', .//column[@name='VRPlanId'])) >0 or //queryError">
        <Cdo>
            <parameters>
                <xsl:for-each select="$distinctOrder">
                    <task id="{concat(column[@name='MSTP'],',',column[@name='MSONPC'])}"/>
                    <action id="{column[@name='VRPlanId']}"/>
                </xsl:for-each>
                <xsl:for-each select="key('k', column[@name='VRPlanId'])">
                    <action id="{column[@name='VRPlanId']}"/>
                </xsl:for-each>
            </parameters>
        </Cdo>
    </xsl:if>
</xsl:template>
<xsl:template match="input"/>
</xsl:stylesheet>

大家好,

感谢您的帮助。 目标是检查我们构建标记的每个不同的VRPlanID值  如果它们在标记的id部分中不为空/空,则将相应的MSTP,MSONPC(不同)分组。 因此,我们在VRPlanID之后进行分组,然后从MSTP / MSONPC的每条记录中获取不同的值。 如果它们是空的,那么只需构建一个虚拟/空消息/标记。 (没做过)

因此,所需的输出将是:

  <output>
   <Cdo>
     <parameters>
       <task id="22,221,2211"/>                
       <action id="1131024"/>
     </parameters>
 </Cdo>
<Cdo>
    <parameters>
       <task id="2221/>                
       <action id="999"/>
    </parameters>
 </Cdo>
  <Cdo>
    <parameters>
       <task id="33,331,222221"/>                
       <action id="11310281"/>
    </parameters>
 </Cdo>
  </output>

稍后编辑:

用这个:

        <!--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="column[@name='MSTP']"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>
    <!--concat all non-duplicates MSTP and MSONPC without last delimiter-->
    <xsl:value-of select="$var.mstp"/>
</xsl:template>

我得到了连锁结果,但没有单独的标签

    <parameters>
            <task id="131957513196231319667"/>
            <action id="11310281"/>
        </parameters>

1 个答案:

答案 0 :(得分:1)

我认为最好防止MSTP和MSONPC中的重复,并将它们放入一个模板中,其中输入参数将是非重复的VRPlanId,如下面的XSL所示:

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

您已编辑过您的XML版本,但如果是以下XML格式:

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

结果是:

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

请注意!在提议的XSL中,对空值进行验证,如果您需要包含它们,只需删除该验证。

如果需要在单独的任务标记中使用每个属性值,则可以在单独的模板中创建任务块结构,并在参数块中调用它,如下所示:

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

然后,当您使用上面的XML检查时,结果将如下所示:

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

当然,您可以在需要的地方添加空白值验证。

希望它对您的案件有所帮助。