按特定值组组,并使用XSLT 1.0生成序列编号

  • 本文关键字:0生 编号 XSLT xml xpath xslt-1.0
  • 更新时间 :
  • 英文 :


我正在尝试基于多个旅行的旅行社可以提供的假期计划。因此,我有多个旅行,必须链接(基于旅行社),并为我访问的每个位置(包括每天的开始和最终位置)生成一个序列号。谢谢你!例如:一个来自一个代理商的2个旅行

旅行天1:

  • 1-开始位置(代理地点)
  • 2-目标1
  • 3-目标2
  • 4-最终位置(酒店)

旅行第二天:

  • 1-开始位置(酒店)
  • 2-目标3
  • 3-最终位置(酒店)

旅行第3天:

  • 1-开始位置(酒店)
  • 2-结束位置(代理地点)

从这3条旅行中,我想这样一次一次旅行:

旅行1:

  • 1-开始位置(代理地点)
  • 2-目标1
  • 3-目标2
  • 4-终点位置(酒店)/从旅行第二天开始的开始位置(这就是为什么我只需要添加一次的原因)
  • 5-目标3
  • 6-旅行第三天的结束位置(酒店)/开始位置(这就是为什么我只需要添加一次的原因)
  • 7-结束位置(代理地点)

输入XML:

<HolidayPlan>
    <!-- first holiday -->
    <Travel>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <StartLocationID>A</StartLocationID>
        <EndLocationID>B</EndLocationID>
        <Day>1</Day>
        <IntermediateObjectives>
            <Objective1>
                <UniqueObjectiveID>Objective1</UniqueObjectiveID>
                <ObjectiveNumber>1</ObjectiveNumber>
            </Objective1>
            <Objective2>
                <UniqueObjectiveID>Objective2</UniqueObjectiveID>
                <ObjectiveNumber>2</ObjectiveNumber>
            </Objective2>
        </IntermediateObjectives>
    </Travel>
    <Travel>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <StartLocationID>B</StartLocationID>
        <EndLocationID>B</EndLocationID>
        <Day>2</Day>
        <IntermediateObjectives>
            <Objective1>
                <UniqueObjectiveID>Objective3</UniqueObjectiveID>
                <ObjectiveNumber>1</ObjectiveNumber>
            </Objective1>
        </IntermediateObjectives>
    </Travel>
    <Travel>
        <UniqueTravelID>100-3</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <StartLocationID>B</StartLocationID>
        <EndLocationID>A</EndLocationID>
        <Day>3</Day>
        <IntermediateObjectives>
        </IntermediateObjectives>
    </Travel>
    <!-- second holiday -->
    <Travel>
        <UniqueTravelID>200-1</UniqueTravelID>
        <TravelAgency>Agency2</TravelAgency>
        <StartLocationID>C</StartLocationID>
        <EndLocationID>D</EndLocationID>
        <Day>1</Day>
        <IntermediateObjectives>
            <Objective1>
                <UniqueObjectiveID>Objective1</UniqueObjectiveID>
                <ObjectiveNumber>1</ObjectiveNumber>
            </Objective1>
        </IntermediateObjectives>
    </Travel>
    <Travel>
        <UniqueTravelID>200-2</UniqueTravelID>
        <TravelAgency>Agency2</TravelAgency>
        <StartLocationID>D</StartLocationID>
        <EndLocationID>C</EndLocationID>
        <Day>2</Day>
        <IntermediateObjectives>
        </IntermediateObjectives>
    </Travel>
</HolidayPlan>

预期结果:

<VisitedPlaces>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>A</UniqueObjectiveID>
        <ObjectiveNumber>1</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>Objective1</UniqueObjectiveID>
        <ObjectiveNumber>2</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>Objective2</UniqueObjectiveID>
        <ObjectiveNumber>3</ObjectiveNumber>
    </Place>
        <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>B</UniqueObjectiveID>
        <ObjectiveNumber>4</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>Objective3</UniqueObjectiveID>
        <ObjectiveNumber>5</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>B</UniqueObjectiveID>
        <ObjectiveNumber>6</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>A</UniqueObjectiveID>
        <ObjectiveNumber>7</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>200-1</UniqueTravelID>
        <TravelAgency>Agency2</TravelAgency>
        <UniqueObjectiveID>C</UniqueObjectiveID>
        <ObjectiveNumber>1</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>200-1</UniqueTravelID>
        <TravelAgency>Agency2</TravelAgency>
        <UniqueObjectiveID>Objerctive1</UniqueObjectiveID>
        <ObjectiveNumber>2</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>200-1</UniqueTravelID>
        <TravelAgency>Agency2</TravelAgency>
        <UniqueObjectiveID>D</UniqueObjectiveID>
        <ObjectiveNumber>3</ObjectiveNumber>
    </Place>
        <Place>
        <UniqueTravelID>200-1</UniqueTravelID>
        <TravelAgency>Agency2</TravelAgency>
        <UniqueObjectiveID>C</UniqueObjectiveID>
        <ObjectiveNumber>4</ObjectiveNumber>
    </Place>
</VisitedPlaces>

i正在为 plote 结构创建模板,以使代码更加清晰,然后为创建 TravelAgency创建结构的模板和通过它们在带有重复项的主要模板中,请参见下面的XSL(在评论中进行了一些说明):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" />
    <!--create Place structure-->
    <xsl:template name="place">
        <xsl:param name="param.travel.id"/>
        <xsl:param name="param.travel.agency"/> 
        <xsl:param name="param.object.id"/>
        <xsl:param name="param.object.number"/>  
        <Place>                
            <UniqueTravelID>                    
                <xsl:value-of select="$param.travel.id"/>                
            </UniqueTravelID>                
            <TravelAgency>                    
                <xsl:value-of select="$param.travel.agency"/>                
            </TravelAgency>                
            <UniqueObjectiveID>                    
                <xsl:value-of select="$param.object.id"/>                                    
            </UniqueObjectiveID>                
            <ObjectiveNumber>                    
                <xsl:value-of select="$param.object.number"/>                
            </ObjectiveNumber>            
        </Place>        
    </xsl:template>    
    <!--create template with Place filter by Agency--> 
    <xsl:template name="filter-place">
        <xsl:param name="param.agency"/>   
        <xsl:for-each select="/HolidayPlan/Travel[TravelAgency = $param.agency]">
            <xsl:variable name="var.travel.id" select="/HolidayPlan/Travel[TravelAgency = $param.agency][1]/UniqueTravelID"/>
            <xsl:variable name="var.travel.agency" select="/HolidayPlan/Travel[TravelAgency = $param.agency][1]/TravelAgency"/>
            <xsl:variable name="var.prev.obj.count" select="count(preceding::Travel[TravelAgency = $param.agency]/IntermediateObjectives//UniqueObjectiveID[1])"/>                      
            <xsl:variable name="var.object.number" select="position() + $var.prev.obj.count"/>
            <!--create day counter from Day-->
            <xsl:variable name="var.day">                    
                <xsl:choose>                        
                    <xsl:when test="normalize-space(Day) = '1'">                            
                        <xsl:value-of select="Day"/>                        
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="Day + $var.prev.obj.count"/>
                    </xsl:otherwise>
                </xsl:choose>                
            </xsl:variable>    
            <!--apply Place structure from Travel-->
            <xsl:call-template name="place">
                <xsl:with-param name="param.travel.id" select="$var.travel.id"/>
                <xsl:with-param name="param.travel.agency" select="$var.travel.agency"/>
                <xsl:with-param name="param.object.id" select="StartLocationID"/>
                <xsl:with-param name="param.object.number" select="$var.day"/>    
            </xsl:call-template>
            <!--apply Place structure from IntermediateObjectives-->            
            <xsl:if test="IntermediateObjectives/*">
                <xsl:for-each select="IntermediateObjectives/*">
                        <xsl:call-template name="place">
                            <xsl:with-param name="param.travel.id" select="$var.travel.id"/>
                            <xsl:with-param name="param.travel.agency" select="$var.travel.agency"/>
                            <xsl:with-param name="param.object.id" select="./UniqueObjectiveID"/>
                            <!--Day counter from IntermediateObjectives-->
                            <xsl:with-param name="param.object.number" select="$var.day + ./ObjectiveNumber"/>
                        </xsl:call-template>               
                </xsl:for-each>
            </xsl:if>
        </xsl:for-each>
        <!--create counter variables for last day-->
        <xsl:variable name="travel.count" select="count(/HolidayPlan/Travel[TravelAgency = $param.agency])" />
        <xsl:variable name="all.obj.count" select="count(/HolidayPlan/Travel[TravelAgency = $param.agency]/IntermediateObjectives/*/UniqueObjectiveID)" /> 
        <!--apply Place structure for last day-->                                       
        <xsl:call-template name="place">
            <xsl:with-param name="param.travel.id" select="/HolidayPlan/Travel[TravelAgency = $param.agency][1]/UniqueTravelID"/>
            <xsl:with-param name="param.travel.agency" select="/HolidayPlan/Travel[TravelAgency = $param.agency][1]/TravelAgency"/>
            <xsl:with-param name="param.object.id" select="/HolidayPlan/Travel[TravelAgency = $param.agency][position() = $travel.count]/EndLocationID"/>
            <!--calculation last counter as next Travel Days + Intermediate Objectives + First Day-->
            <xsl:with-param name="param.object.number" select="$travel.count + $all.obj.count + 1"/>
        </xsl:call-template>                                         
    </xsl:template>
    <!--main template - VisitedPlaces structure-->
    <xsl:template match="/"> 
        <VisitedPlaces>                                                               
            <xsl:for-each select="/HolidayPlan/Travel">
                <!--preventing TravelAgency values duplicates and pass to filter-place template as parameter-->            
                <xsl:if test="not(preceding::Travel[TravelAgency/text() = current()/TravelAgency/text()])">                                                    
                    <xsl:call-template name="filter-place">                                            
                        <xsl:with-param name="param.agency" select="./TravelAgency"/>                                    
                    </xsl:call-template>                          
                </xsl:if>                 
            </xsl:for-each>
        </VisitedPlaces>         
    </xsl:template>
</xsl:stylesheet>

和预期的结果:

<?xml version="1.0" encoding="UTF-8"?>
<VisitedPlaces>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>A</UniqueObjectiveID>
        <ObjectiveNumber>1</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>Objective1</UniqueObjectiveID>
        <ObjectiveNumber>2</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>Objective2</UniqueObjectiveID>
        <ObjectiveNumber>3</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>B</UniqueObjectiveID>
        <ObjectiveNumber>4</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>Objective3</UniqueObjectiveID>
        <ObjectiveNumber>5</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>B</UniqueObjectiveID>
        <ObjectiveNumber>6</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>100-1</UniqueTravelID>
        <TravelAgency>Agency1</TravelAgency>
        <UniqueObjectiveID>A</UniqueObjectiveID>
        <ObjectiveNumber>7</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>200-1</UniqueTravelID>
        <TravelAgency>Agency2</TravelAgency>
        <UniqueObjectiveID>C</UniqueObjectiveID>
        <ObjectiveNumber>1</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>200-1</UniqueTravelID>
        <TravelAgency>Agency2</TravelAgency>
        <UniqueObjectiveID>Objective1</UniqueObjectiveID>
        <ObjectiveNumber>2</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>200-1</UniqueTravelID>
        <TravelAgency>Agency2</TravelAgency>
        <UniqueObjectiveID>D</UniqueObjectiveID>
        <ObjectiveNumber>3</ObjectiveNumber>
    </Place>
    <Place>
        <UniqueTravelID>200-1</UniqueTravelID>
        <TravelAgency>Agency2</TravelAgency>
        <UniqueObjectiveID>C</UniqueObjectiveID>
        <ObjectiveNumber>4</ObjectiveNumber>
    </Place>
</VisitedPlaces> 

希望它对您的情况有所帮助。

相关内容

  • 没有找到相关文章

最新更新