开发者

Xslt access previous element of the for-each loop

开发者 https://www.devze.com 2023-02-06 21:34 出处:网络
Suppose we have the following source xml. <Data Key=\"SS_001PG\" OC:DataId=\"001PG\" OC:UniqueIdentifier=\"01-003\"

Suppose we have the following source xml.

<Data Key="SS_001PG"
      OC:DataId="001PG"
      OC:UniqueIdentifier="01-003"
      OC:Status="available"
      OC:DateOfBirth="2010-06-29"
      OC:Sex="m">
    <Event EventOID="123"
           OC:EventLocation="we"
           OC:StartDate="2010-07-12"
           OC:Status="started"
           OC:Age="0"
           EventRepeatKey="1"></Event>
    <Event Even开发者_如何学编程tOID="123"
           OC:StartDate="2010-07-14"
           OC:Status="started"
           OC:Age="0"
           EventRepeatKey="2"></Event>
</Data>
<Data Key="SS_1"
      OC:DataId="1"
      OC:UniqueIdentifier="1"
      OC:Status="available"
      OC:DateOfBirth="2010-07-14"
      OC:Sex="m">
    <Event EventOID="123"
           OC:StartDate="2010-07-16"
           OC:EndDate="2010-07-14"
           OC:Status="started"
           OC:Age="-1"
           EventRepeatKey="1"></Event>
</Data>

We have the following xslt code to process it.

<xsl:variable name="repeatedEvents" select="//Event[@EventOID='123']"/>
<xsl:for-each select="$repeatedEvents">
    <xsl:sort select="@EventRepeatKey" data-type="number"/>
    <xsl:variable name="prevIndex" select="position()-1"/>
    <xsl:variable name="prevEvent"
                  select="$repeatedEvents[position()=$prevIndex]"/>
    <xsl:choose>
        <xsl:when test="position()=1">
            <xsl:value-of select="@EventRepeatKey"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:if test="$prevEvent/@EventRepeatKey != @EventRepeatKey">
                <xsl:value-of select="@EventRepeatKey"/>
            </xsl:if>
        </xsl:otherwise>
    </xsl:choose>
</xsl:for-each>

Now, as you can see, we are selecting all Events having the same EventOID and then sort the elements using EventRepeatkey. So, after the sorting, the Event under the second Data gets in between the Events of the first Data. Inside the loop, while the second element is being processed, We can access the first element using previous index, but when the third element is being processed, We can’t access the second element using the previous index. Is this because the second element is in a lower position in the tree than the third element? Any suggestion how we could solve the problem?

Can someone help?


It seems that you want to perform grouping.

Here is a simple use of the Muenchian method for grouping:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kEvByRepK" match="Event[@EventOID='123']"
          use="@EventRepeatKey"/>

 <xsl:template match=
   "Event[@EventOID='123'
             and
             generate-id()
             =
              generate-id(key('kEvByRepK', @EventRepeatKey)[1])
          ]">
  <xsl:value-of select="@EventRepeatKey"/>
  <xsl:text>&#xA;</xsl:text>
 </xsl:template>
</xsl:stylesheet>

when this transformation is performed on the following XML document (wrapping the provided non-well-formed fragment):

<t xmlns:OC="my:OC" >
    <Data Key="SS_001PG" OC:DataId="001PG" OC:UniqueIdentifier="01-003"
 OC:Status="available" OC:DateOfBirth="2010-06-29" OC:Sex="m">
        <Event EventOID="123" OC:EventLocation="we" OC:StartDate="2010-07-12"
 OC:Status="started" OC:Age="0" EventRepeatKey="1"/>
        <Event EventOID="123" OC:StartDate="2010-07-14" OC:Status="started"
 OC:Age="0"
        EventRepeatKey="2"/>
    </Data>
    <Data Key="SS_1" OC:DataId="1" OC:UniqueIdentifier="1" OC:Status="available"
 OC:DateOfBirth="2010-07-14"  OC:Sex="m">
        <Event EventOID="123" OC:StartDate="2010-07-16" OC:EndDate="2010-07-14" 
OC:Status="started" OC:Age="-1" EventRepeatKey="1"/>
    </Data>
</t>

the wanted, correct result is produced:

1
2

Explanation: Read about the Muenchian method for grouping.

0

精彩评论

暂无评论...
验证码 换一张
取 消