XSLT组(如果条件匹配) [英] XSLT group if condition is matched

查看:70
本文介绍了XSLT组(如果条件匹配)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

输入:

  <?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(区别)不是null/empty,则将它们分组. 因此,我们将VRPlanID分组,然后从MSTP/MSONPC的每个记录中获得不同的值. 如果它们为空,则只需构建一个虚拟/空消息/标签. (未完成)

Thanks for your help. The goal is to check for every distinct VRPlanID value that we build the tag Group the corresponding MSTP, MSONPC (distinct) if they're not null/empty in the id part of the tag. So, we group after VRPlanID, then get the distinct values from each record from MSTP/MSONPC. If they're empty then just build a dummy / null message/tag. (not done)

因此,所需的输出将是:

So, the desired output would be:

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

我得到了合并结果,但是没有单独的标签

I get the concatenated results, but not in separate tags

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

推荐答案

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

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>

您已经编辑了XML版本,但在以下情况下使用了XML:

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>

结果是:

<?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中,存在对空值的验证,如果您需要包括空值,则只需删除该验证即可.

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>

然后,当您使用XML对其进行检查时,结果将如下所示:

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.

这篇关于XSLT组(如果条件匹配)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆