XSLT Increment reset upon change in element

时间:2017-12-18 06:57:17

标签: xslt-1.0

XML:

<?xml version="1.0" encoding="utf-8"?>
  <Projects> 
    <Project GUID="K9"> 
    <Name>Range</Name>
    <WBSs>
        <WBS GUID="2">
            <Name>Site</Name>
            <ParentWBS/>
            <ProjectGUID>K9</ProjectGUID>
            <ObjectId>99040</ObjectId>
            <Activities/>
            <WBSs>
                <WBS GUID="1">
                <Name>West</Name>
                <ParentWBS>2</ParentWBS>
                <ProjectGUID>K9</ProjectGUID>
                <ObjectId>99046</ObjectId>
                <Activities>
                  <Activity GUID="A100">
                    <Name>Task</Name>
                    <ProjectGUID>K17</ProjectGUID>
                    <WBSCode>1</WBSCode>
                  </Activity>
                </Activities>
             </WBS>
             <WBS GUID="2">
                 <Name>South</Name>
                 <ParentWBS>2</ParentWBS>
                 <ProjectGUID>K9</ProjectGUID>
                 <ObjectId>99047</ObjectId>
                 <Activities>
                   <Activity GUID="A200">
                     <Name>Task 2</Name>
                   </Activity>
                 </Activities>
             </WBS>
             <WBS GUID="3">
                 <Name>North</Name>
                 <ParentWBS>2</ParentWBS>
                 <ProjectGUID>K9</ProjectGUID>
                 <ObjectId>99048</ObjectId>
                 <Activities/>
             </WBS>
          </WBSs>
      </WBS>
    </WBSs>
    <Activities/>
  </Project>
</Projects>

This is my current output:

<OBJECTID>99046</OBJECTID >
<ACTIVITY>0010</ACTIVITY>
<OBJECTID>99047</OBJECTID >
<ACTIVITY>0020</ACTIVITY>

Desired output:

<OBJECTID>99046</OBJECTID >
<ACTIVITY>0010</ACTIVITY>
<OBJECTID>99047</OBJECTID >
<ACTIVITY>0010</ACTIVITY>

When I have existing Activity and existing OBJECTID, the first 2 WHEN clauses work fine. The problem arises when there is no existing ObjectID or ObjectID changes in the 3rd WHEN. What I need is to start at ‘0010’ and increment by 10 until $ObjectID changes, then start at ‘0010’ again and so on. My background is procedural programming so still getting used to functional way of doing things and the restriction of not changing variables. Thanks in advance.

Here's the relevant XSLT code:

<ACTIVITY> 
<!-- count($ExistingActivity) = 1 -> ObjectId & Activity Id exist, increment $LastObjectIdActivity/ACTIVITY
   count($ExistingObjectId) = 1 -> ObjectId exists, increment $LastObjectId/ACTIVITY  
   count($ExistingObjectId) = 0 -> $ObjectId start at 0010 and keep incrementing until ObjectId change. 
-->
   <xsl:variable name="incr" select="10"/>
     <xsl:choose>
        <xsl:when test="count($ExistingActivity) = 1">      <!-- Exact match of ObjectId & Activity -->
        <!-- Get last existing ObjectId activity -->                        
          <xsl:variable name="temp" select="$LastObjectIdActivity/ACTIVITY"/>                                 
          <xsl:variable name="Oper" select="format-number($temp, '0000')"/>                              
          <xsl:value-of select="$Oper"/>
        </xsl:when>
        <xsl:when test="count($ExistingObjectId) = 1"> <!-- Activity not found, But ObjectId exists-->
        <!-- Get last existing ObjectId activity -->
          <xsl:variable name="temp" select="$LastObjectId/ACTIVITY + $incr"/>                                 
          <xsl:variable name="Oper" select="format-number($temp, '0000')"/>                              
          <xsl:value-of select="$Oper"/>
        </xsl:when>                                                                            
        <xsl:when test="count($ExistingObjectId) = 0">   <!-- No Existing ObjectId -->
          <xsl:variable name="pos" select="(position() * 10)"/>  
          <xsl:variable name="NextOper" select="format-number($pos, '0000')"/>  <!-- Start Activity at 0010 reset on new ObjectId-->
          <xsl:value-of select="$NextOper"/>
          <!-- $NextOper should be incremented by 10 -->                           
        </xsl:when> 
        <xsl:otherwise>
        </xsl:otherwise>                           
     </xsl:choose>                    
</ACTIVITY>

1 个答案:

答案 0 :(得分:0)

我认为你想要的是为每个活动分配一个值,这就是你想要匹配的东西

<xsl:template match="//Activity">
<OBJECTID>
    <xsl:value-of select="../../ObjectId" />
</OBJECTID>
<ACTIVITY>
    <xsl:value-of select="format-number(10 * (count(preceding-sibling::*) +1), '0000') "/>
</ACTIVITY>
</xsl:template>

这会为输入中的每个活动提供OBJECTID / ACTIVITY对。 count表达式评估先前兄弟活动的数量,即从1开始的索引。