Question

How can I check when it is the first time the program runs the <xsl:if test="$DriverCount > 1"> statement so that the program does something only once. And when is the last time it runs the same if statement so that it does something else only once? position() and number doesnt work as the if statement dont always run on position() = 1. I cant use template function and cant write any XSL functions as I am using XF designer and those keywords cant be used there.

XML

<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
   <DETAILS>
      <NAME>SANNIE</NAME>
      <SURNAME>DELANGE</SURNAME>
   </DETAILS>
   <INSURANCE_ITEMS>
      <VEHICLE>
         <XMLDOC_VEHICLE>
            <REGULAR_DRIVER_DETAILS>
               <DRIVER_NAME>SAM</DRIVER_NAME>
               <VEH>POLO</VEH>
            </REGULAR_DRIVER_DETAILS>
         </XMLDOC_VEHICLE> -<XMLDOC_VEHICLE>
            <REGULAR_DRIVER_DETAILS>
               <DRIVER_NAME>SANNIE</DRIVER_NAME>
               <VEH>GOLF</VEH>
            </REGULAR_DRIVER_DETAILS>
         </XMLDOC_VEHICLE> <XMLDOC_VEHICLE>
            <REGULAR_DRIVER_DETAILS>
               <DRIVER_NAME>SANNIE</DRIVER_NAME>
               <VEH>GOLF</VEH>
            </REGULAR_DRIVER_DETAILS>
         </XMLDOC_VEHICLE> <XMLDOC_VEHICLE>
            <REGULAR_DRIVER_DETAILS>
               <DRIVER_NAME>SAM</DRIVER_NAME>
               <VEH>MAZDA</VEH>
            </REGULAR_DRIVER_DETAILS>
         </XMLDOC_VEHICLE>
      </VEHICLE>
   </INSURANCE_ITEMS>
</ROOT>

XSL

<xsl:for-each select="/ROOT/INSURANCE_ITEMS/VEHICLE/XMLDOC_VEHICLE[not(REGULAR_DRIVER_DETAILS/DRIVER_NAME = preceding-sibling::XMLDOC_VEHICLE/REGULAR_DRIVER_DETAILS/DRIVER_NAME )]">
   <xsl:variable select="REGULAR_DRIVER_DETAILS/DRIVER_NAME" name="Driver"/>
   <xsl:variable select="count(/ROOT/INSURANCE_ITEMS/VEHICLE/XMLDOC_VEHICLE/REGULAR_DRIVER_DETAILS[DRIVER_NAME=$Driver])" name="DriverCount"/>
   <xsl:if test="$DriverCount > 1">
      <xsl:value-of select="'Hello '"/>
      <xsl:value-of select="REGULAR_DRIVER_DETAILS/DRIVER_NAME"/>
      <xsl:value-of select="' your cars are: '"/>
      <xsl:for-each select="/ROOT/INSURANCE_ITEMS/VEHICLE/XMLDOC_VEHICLE[REGULAR_DRIVER_DETAILS/DRIVER_NAME=$Driver]">
         <xsl:value-of select="REGULAR_DRIVER_DETAILS/VEH"/>
         <xsl:if test="$Driver = following-sibling::XMLDOC_VEHICLE/REGULAR_DRIVER_DETAILS/DRIVER_NAME">
            <xsl:value-of select="' and '"/>
         </xsl:if>
      </xsl:for-each>
   </xsl:if>
</xsl:for-each>
Was it helpful?

Solution 2

Thanks, the muenchian method solved my problem.

<xsl:for-each select="INSURANCE_ITEMS/VEHICLE/XMLDOC_VEHICLE[count(. | key('cars-by-driver', REGULAR_DRIVER_DETAILS/DRIVER_NAME)[1]) = 2 and not(REGULAR_DRIVER_DETAILS/DRIVER_NAME = following-sibling::XMLDOC_VEHICLE/REGULAR_DRIVER_DETAILS/DRIVER_NAME )]">

  <xsl:if test="position() != 1">
    <xsl:value-of select="'; and '"/>
  </xsl:if>
  <xsl:if test="position() = 1">
    <xsl:value-of select="'We note that '"/>
  </xsl:if>

  <xsl:value-of select="REGULAR_DRIVER_DETAILS/DRIVER_NAME"/>
  <xsl:value-of select="' is noted as the regular driver on more than one vehicle: '"/>
  <xsl:for-each select="key('cars-by-driver', REGULAR_DRIVER_DETAILS/DRIVER_NAME)">
    <xsl:value-of select="VEH"/>

    <xsl:choose>
      <xsl:when test="position() &lt; last() - 1">
        <xsl:value-of select="', '"/>
      </xsl:when>
      <xsl:when test="position() = last() - 1">
        <xsl:value-of select="' and '"/>
      </xsl:when>
    </xsl:choose>

  </xsl:for-each>
  <xsl:if test="position() = last()">
    <xsl:value-of select="'. Remember: it is imperative that you supply the details of the correct regular driver, which is the individual who will be driving the vehicle most often in any monthly period, as the premium is calculated on the profile of that person.'"/>
  </xsl:if>
</xsl:for-each>

using XML:

<INSURANCE_ITEMS>
    <VEHICLE>
        <XMLDOC_VEHICLE>    
            <VEH>POLO</VEH>
            <REGULAR_DRIVER_DETAILS>
                <DRIVER_NAME>SANNIE</DRIVER_NAME>           
            </REGULAR_DRIVER_DETAILS>
        </XMLDOC_VEHICLE>
        <XMLDOC_VEHICLE>    
        <VEH>HYUNDAI</VEH>
            <REGULAR_DRIVER_DETAILS>
                <DRIVER_NAME>SAREL</DRIVER_NAME>
                </REGULAR_DRIVER_DETAILS>
        </XMLDOC_VEHICLE>
        <XMLDOC_VEHICLE>    
        <VEH>GOLF</VEH>
            <REGULAR_DRIVER_DETAILS>
                <DRIVER_NAME>SAM</DRIVER_NAME>                  
            </REGULAR_DRIVER_DETAILS>
        </XMLDOC_VEHICLE>
        <XMLDOC_VEHICLE>    
        <VEH>MAZDA</VEH>
            <REGULAR_DRIVER_DETAILS>
                <DRIVER_NAME>SAM</DRIVER_NAME>
                </REGULAR_DRIVER_DETAILS>
        </XMLDOC_VEHICLE>
        <XMLDOC_VEHICLE>    
        <VEH>BAKKIE</VEH>
            <REGULAR_DRIVER_DETAILS>
                <DRIVER_NAME>SAREL</DRIVER_NAME>
                </REGULAR_DRIVER_DETAILS>
        </XMLDOC_VEHICLE>
    </VEHICLE>
</INSURANCE_ITEMS>

THE OUTPUT:

We note that SAM is noted as the regular driver on more than one vehicle: GOLF and MAZDA; and SAREL is noted as the regular driver on more than one vehicle: HYUNDAI and BAKKIE. Remember: it is imperative that you supply the details of the correct regular driver, which is the individual who will be driving the vehicle most often in any monthly period, as the premium is calculated on the profile of that person.

OTHER TIPS

You can add a further check for no other REGULAR_DRIVER_DETAILS/VEH after the current one of the same type with an additional filter:

<xsl:for-each select="/ROOT/INSURANCE_ITEMS/VEHICLE/XMLDOC_VEHICLE
 [REGULAR_DRIVER_DETAILS/DRIVER_NAME=$Driver]
 [not(following::REGULAR_DRIVER_DETAILS/VEH = REGULAR_DRIVER_DETAILS/VEH)]">

Result:

Hello SAM your cars are: POLO and MAZDAHello SANNIE your cars are: GOLF

i.e. Sannie's other GOLF is omitted.

However, this whole approach looks very imperative indeed. Possibly time for a new tool :-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top