Little help for XSLT - "do nothing for no-match"

Questions about writing stylesheets for transforming (Tools > Transform Tasklist) your tasklist

Moderator: abstr

Post Reply
Peter2
Posts: 174
Joined: Fri Aug 02, 2019 7:58 pm

Little help for XSLT - "do nothing for no-match"

Post by Peter2 » Mon Apr 22, 2024 2:40 pm

I tried this simple XSLT to transform a few values to txt/csv

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="utf-8" />
    <xsl:template match="TODOLIST/TASK/TASK">
        <xsl:value-of select="./PERSON" />
        <xsl:text>&#0009;</xsl:text>
        <xsl:value-of select="../@TITLE" />
        <xsl:text>&#0009;</xsl:text>
        <xsl:value-of select="./@TITLE" />
        <xsl:text>&#0009;</xsl:text>
        <xsl:value-of select="./@STARTDATESTRING" />
        <xsl:text>&#0009;</xsl:text>
        <xsl:value-of select="./@DUEDATESTRING" />
        <xsl:text>&#xa;</xsl:text>
    </xsl:template>

</xsl:stylesheet>
This part works as expected, but it also write all nodes "PERSON" - which are not matched - to the file.. ?? I expected that only the "matches" are handled and the not-matches are ignored by itself.

What's wrong here?
Thanks for advice!

User avatar
zonfeld
Posts: 173
Joined: Sun Mar 21, 2021 11:41 am
Contact:

Re: Little help for XSLT - "do nothing for no-match"

Post by zonfeld » Wed Apr 24, 2024 3:14 pm

I might be able to help you but I don't understand what you're trying to achieve. Would you please explain what output you're expecting and provide a minimal TDL example file? Thank you.

Peter2
Posts: 174
Joined: Fri Aug 02, 2019 7:58 pm

Re: Little help for XSLT - "do nothing for no-match"

Post by Peter2 » Wed Apr 24, 2024 4:18 pm

Hi zonfeld

thanks for offering your help. Just now while preparing the data I saw that the mess is bigger then expected ...

Attached a simple file with fake date:
- few main tasks
- some sub-taks with start, due-date and "allocated to"

The XSLT should create a CSV (nearly) like the attached CSV: per subtasks a row with
"Parent task - task - start - due - allocated to"

(Obvious) problem 1:
- in line 6 it writes all the data from the (possible) list of "allocated to" entries

problem 2:
- in reality, it does not filter / match anything. It writes everything out to CSV, and the reason why the CSV looks "rather good" is only - there are no more data in the TDL...

It would be nice if you are interested in it, but please don't take to much time for it. it should be my workload ..
Attachments
res_to_csv_det.xslt
(821 Bytes) Downloaded 3 times
res_test.tdl
(37.61 KiB) Downloaded 3 times
res_test.csv
(876 Bytes) Downloaded 3 times

User avatar
zonfeld
Posts: 173
Joined: Sun Mar 21, 2021 11:41 am
Contact:

Re: Little help for XSLT - "do nothing for no-match"

Post by zonfeld » Wed Apr 24, 2024 6:35 pm

Thank you for the files and no worries: I like puzzles. I haven't had to work with XSLT for so long that I've become rusty and this seems like a fun little distraction. :)

You're getting unexpected additional output because you probably didn't know that there's such a thing as a default template. The default template basically copies everything it finds that is not matched by another template. In your case, only the <PERSON> and <TAG> elements contain text and that's what you see. If, for example, you put some text right before the closing </TODOLIST> tag, that would appear as well.

That should no longer be a problem with the following transformation, which suppresses everything unless it's explicitly handled by a template. It also looked like you wanted to use TAB delimiters, so I added those instead of the spaces and used the newline character at the end.

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" encoding="utf-8"/>

  <xsl:template match="TODOLIST/TASK/TASK">
    <xsl:value-of select="./PERSON"/>
    <xsl:text>&#x9;</xsl:text>
    <!-- use TAB delimiters -->
    <xsl:value-of select="../@TITLE"/>
    <xsl:text>&#x9;</xsl:text>
    <xsl:value-of select="./@TITLE"/>
    <xsl:text>&#x9;</xsl:text>
    <xsl:value-of select="./@STARTDATESTRING"/>
    <xsl:text>&#x9;</xsl:text>
    <xsl:value-of select="./@DUEDATESTRING"/>
    <xsl:text>&#xA;</xsl:text>
    <!-- newline character -->
  </xsl:template>

  <!-- ignore all -->
  <xsl:template match="*|@*|comment()|processing-instruction()|text()">
    <xsl:apply-templates select="*|@*|comment()|processing-instruction()|text()"/>
  </xsl:template>
</xsl:stylesheet>
What I still don't understand is the part where you're expecting some kind of filtering. You might have to elaborate on that.

Right now, the template does exactly what you're asking it to. Whenever it finds a path that matches "TODOLIST/TASK/TASK", it dives into the template. It then outputs the value of the PERSON child followed by the delimiter. Afterwards, it looks at the parent node and outputs its TITLE attribute, and so forth.

What elements do you expect to be filtered out based on what condition?

Peter2
Posts: 174
Joined: Fri Aug 02, 2019 7:58 pm

Re: Little help for XSLT - "do nothing for no-match"

Post by Peter2 » Thu Apr 25, 2024 7:32 am

Thanks @zonfeld

that's exactly what I wanted.
Sorry about the confusion about the word "filter" - I mixed it up with "match =". I hope this is a snippet which can inspire other user too.

User avatar
zonfeld
Posts: 173
Joined: Sun Mar 21, 2021 11:41 am
Contact:

Re: Little help for XSLT - "do nothing for no-match"

Post by zonfeld » Thu Apr 25, 2024 7:58 am

You're welcome. I'm glad I could help.

Post Reply