Adee
Adee

Reputation: 67

Lookup for a date in a list of holidays if present or not using XSLT

I have a xml with list of holidays:

<root>
  <row>
    <Date>2021-01-01</Date>
  </row>
  <row>
    <Date>2021-02-05</Date>
  </row>

...

I have an input xml with a date field in it:

<Report_data>
  <Report_entry>
    <Input_date>2021-01-01</Input_date>
  </Report_entry>
  <Report_entry>
    <Input_date>2021-01-15</Input_date>
  </Report_entry>

...

I want to read the input xml and output a true/false value based on the Input_date is present in the list of holidays. Expected output:

<Data>
  <output>
    <Input_date>2021-01-01</Input_date>
    <Flag>True</Flag>
  </output>
  <output>
    <Input_date>2021-01-15</Input_date>
    <Flag>False</Flag>
  </output>

...

Can it be done using XSLT 3.0 ?

Upvotes: 0

Views: 117

Answers (2)

Martin Honnen
Martin Honnen

Reputation: 167696

While the posted solution solves the problem, in XSLT 3 there are more elegant and compact ways, using a key on the secondary input document provided as a parameter, using template matching and text value templates:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">
    
  <xsl:param name="holidays">
      <rows>
          <row>
            <Date>2021-01-01</Date>
          </row>
          <row>
            <Date>2021-02-05</Date>
          </row>
      </rows>
  </xsl:param>
    
  <xsl:key name="date" match="rows/rows/Date" use="."/>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml" indent="yes"/>
  
  <xsl:template match="Report_entry/Input_date">
      <xsl:next-match/>
      <Flag>{exists([key('date', ., $holidays)])}</Flag>
  </xsl:template>
  
  <xsl:template match="Report_data">
      <Data>
          <xsl:apply-templates/>
       </Data>
  </xsl:template>
    
  <xsl:template match="Report_entry">
      <output>
          <xsl:apply-templates/>
      </output>
  </xsl:template>
  
</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/asoTKv/1

Upvotes: 1

sspsujit
sspsujit

Reputation: 301

You have not mentioned what have you done so far. Still I assume, you have an XSL working with you which need be updated.

here, a variable is used to store the list of holidays:

  <xsl:variable name="holidays" as="node()">
      <rows>
          <row>
            <Date>2021-01-01</Date>
          </row>
          <row>
            <Date>2021-02-05</Date>
          </row>
      </rows>
  </xsl:variable> 

then you need to compare those values with your input:

<xsl:template match="Report_entry">
    <xsl:element name="output">
        <xsl:apply-templates/>
        <xsl:element name="Flag">
            <xsl:choose>
                <xsl:when test="$holidays//Date = Input_date">
                    <xsl:text>TRUE</xsl:text>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>False</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:element>
    </xsl:element>
  </xsl:template> 

test: https://xsltfiddle.liberty-development.net/asoTKv

Upvotes: 1

Related Questions