Home > other >  Reference the current node in a document tree, which is stored in a variable
Reference the current node in a document tree, which is stored in a variable

Time:10-16

I have a stylesheet in which I loop through a Day-Element. For each day, I need to get a value from another XML-document, which i have inside a parameter, referenced with $ArtStat.

If I use the filter as a fixed value of 2022-10-11, it works fine

<xsl:for-each select="Day">
    <QtyOut><xsl:value-of select="$ArtStat/ECRArtStat/Days/Day[Date='2022-10-11']/QtyOut" /></QtyOut>
</xsl:for-each>

But I need to use the filter as a dynamic value (the content of the current node), and that doesnt work (the result in this case is that this select gives back an empty String ""

<xsl:for-each select="Day">
    <QtyOut><xsl:value-of select="$ArtStat/ECRArtStat/Days/Day[Date=current()]/QtyOut" /></QtyOut>
</xsl:for-each>

I tried it with current() or 'current()', with ., with self:node(), anything didnt work at all I guess there is a simple solution with it, but I can't find it. I could use XSLT 2.0 or 3.0 with Saxon 9

The explanation above is a simplification of my issue. Cause actually what I need is: For each day on my XML document, I need to check the QtyOut-value inside another document and I need to sum them to one value. So something like this:

sum($ArtStat/ECRArtStat/Days/Day[Date=<Nodeset of the days>]/QtyOut)

but this I couldn't solve directly with XSL, so I try to set a variable first, and after sum the content, like this:

<xsl:variable name="QtyOutList">
   <xsl:for-each select="Day">
       <QtyOut><xsl:value-of select="$ArtStat/ECRArtStat/Days/Day[Date=current()]/QtyOut" /></QtyOut>
   </xsl:for-each>
</xsl:variable>
<xsl:value-of select="sum($QtyOutList/QtyOut)" />

This does work if I use a fixed value for the date, but not with current(),....

Source XML (the source doc define for which days we need to get the values):

<Columns>
  <Column type="pastWeek">
    <WeekNo>40</WeekNo>
    <Year>2022</Year>
    <StartDay>2022-10-03</StartDay>
  </Column>
  <Column type="currentWeek">
    <WeekNo>41</WeekNo>
    <Year>2022</Year>
    <StartDay>2022-10-10</StartDay>
    <Day>2022-10-10</Day>
    <Day>2022-10-11</Day>
    <Day>2022-10-12</Day>
    <Day>2022-10-13</Day>
    <Day>2022-10-14</Day>
    <Day>2022-10-15</Day>
  </Column>
</Columns>

Referenced XML as a variable (where I need to get the QtyOut value from):

<ECRArtStat>
  <Days>
    <Day>
      <Date>2022-10-13</Date>
      <QtyIn>0</QtyIn>
      <QtyOut>0</QtyOut>
    </Day>
    <Day>
      <Date>2022-10-12</Date>
      <QtyIn>0</QtyIn>
      <QtyOut>0</QtyOut>
    </Day>
    <Day>
      <Date>2022-10-11</Date>
      <QtyIn>0</QtyIn>
      <QtyOut>5</QtyOut>
     </Day>
     <Day>
       <Date>2022-10-10</Date>
       <QtyIn>0</QtyIn>
       <QtyOut>4</QtyOut>
     </Day>

CodePudding user response:

If I do e.g.

<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:mode on-no-match="shallow-copy"/>
  
  <xsl:template match="Column[Day]">
    <xsl:comment>Sum {sum($ArtStat/ECRArtStat/Days/Day[Date = current()/Day]/QtyOut)}</xsl:comment>
    <xsl:next-match/>
  </xsl:template>

  <xsl:param name="ArtStat">
<ECRArtStat>
  <Days>
    <Day>
      <Date>2022-10-13</Date>
      <QtyIn>0</QtyIn>
      <QtyOut>0</QtyOut>
    </Day>
    <Day>
      <Date>2022-10-12</Date>
      <QtyIn>0</QtyIn>
      <QtyOut>0</QtyOut>
    </Day>
    <Day>
      <Date>2022-10-11</Date>
      <QtyIn>0</QtyIn>
      <QtyOut>5</QtyOut>
     </Day>
     <Day>
       <Date>2022-10-10</Date>
       <QtyIn>0</QtyIn>
       <QtyOut>4</QtyOut>
     </Day>
  </Days>
</ECRArtStat>
  </xsl:param>
  
</xsl:stylesheet>

against an input of e.g.

<Columns>
  <Column type="pastWeek">
    <WeekNo>40</WeekNo>
    <Year>2022</Year>
    <StartDay>2022-10-03</StartDay>
  </Column>
  <Column type="currentWeek">
    <WeekNo>41</WeekNo>
    <Year>2022</Year>
    <StartDay>2022-10-10</StartDay>
    <Day>2022-10-10</Day>
    <Day>2022-10-11</Day>
    <Day>2022-10-12</Day>
    <Day>2022-10-13</Day>
    <Day>2022-10-14</Day>
    <Day>2022-10-15</Day>
  </Column>
</Columns>

the result is e.g.

<?xml version="1.0" encoding="UTF-8"?><Columns>
  <Column type="pastWeek">
    <WeekNo>40</WeekNo>
    <Year>2022</Year>
    <StartDay>2022-10-03</StartDay>
  </Column>
  <!--Sum 9--><Column type="currentWeek">
    <WeekNo>41</WeekNo>
    <Year>2022</Year>
    <StartDay>2022-10-10</StartDay>
    <Day>2022-10-10</Day>
    <Day>2022-10-11</Day>
    <Day>2022-10-12</Day>
    <Day>2022-10-13</Day>
    <Day>2022-10-14</Day>
    <Day>2022-10-15</Day>
  </Column>
</Columns>

meaning a sum is computed based on the reference values.

As you pretend to ask questions about XSLT 3 but don't understand the use of text value templates or xsl:next-match, 2022-10-13 0 0 2022-10-12 0 0 2022-10-11 0 5 2022-10-10 0 4 &input= 40 2022 2022-10-03 41 2022 2022-10-10 2022-10-10 2022-10-11 2022-10-12 2022-10-13 2022-10-14 2022-10-15 &input-type=XML" rel="nofollow noreferrer">here is an example using xsl:value-of:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">
  
  <xsl:mode on-no-match="shallow-copy"/>
  
  <xsl:template match="Column[Day]">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
      <Sum>
        <xsl:value-of select="sum($ArtStat/ECRArtStat/Days/Day[Date = current()/Day]/QtyOut)"/>
      </Sum>
    </xsl:copy>
  </xsl:template>

  <xsl:param name="ArtStat">
<ECRArtStat>
  <Days>
    <Day>
      <Date>2022-10-13</Date>
      <QtyIn>0</QtyIn>
      <QtyOut>0</QtyOut>
    </Day>
    <Day>
      <Date>2022-10-12</Date>
      <QtyIn>0</QtyIn>
      <QtyOut>0</QtyOut>
    </Day>
    <Day>
      <Date>2022-10-11</Date>
      <QtyIn>0</QtyIn>
      <QtyOut>5</QtyOut>
     </Day>
     <Day>
       <Date>2022-10-10</Date>
       <QtyIn>0</QtyIn>
       <QtyOut>4</QtyOut>
     </Day>
  </Days>
</ECRArtStat>
  </xsl:param>
  
</xsl:stylesheet>

Output is e.g.

<Columns>
  <Column type="pastWeek">
    <WeekNo>40</WeekNo>
    <Year>2022</Year>
    <StartDay>2022-10-03</StartDay>
  </Column>
  <Column type="currentWeek">
    <WeekNo>41</WeekNo>
    <Year>2022</Year>
    <StartDay>2022-10-10</StartDay>
    <Day>2022-10-10</Day>
    <Day>2022-10-11</Day>
    <Day>2022-10-12</Day>
    <Day>2022-10-13</Day>
    <Day>2022-10-14</Day>
    <Day>2022-10-15</Day>
  <Sum>9</Sum></Column>
</Columns>
  • Related