Can't match the topic/pre class

Here should go questions about transforming XML with XSLT and FOP.
gbv34
Posts: 105
Joined: Thu Jan 20, 2022 12:36 pm

Can't match the topic/pre class

Post by gbv34 »

Hello, everyone!
I'm currently trying to write an XSLT that matches a specific outputclass value and depending on the class, I need to display a specific label beforehand.
I rely on a temporary output from a DITA concept.
Here is a short sample:

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<concept xmlns:ditaarch="http://dita.oasis-open.org/architecture/2005/" xmlns:dita-ot="http://dita-ot.sourceforge.net/ns/201007/dita-ot" class="- topic/topic concept/concept " ditaarch:DITAArchVersion="1.3" domains="(topic concept) (topic reference) (topic task) (topic concept glossentry) (topic concept glossgroup) (topic troubleshooting++task) (topic task) (topic abbrev-d) a(props deliveryTarget) (topic hazard-d) (topic hi-d) (topic indexing-d) (topic markup-d) (topic pr-d) (topic svg-d) (topic sw-d) (topic ui-d) (topic ut-d) (topic task strictTaskbody-c) a(base xxxxxx_locid) (topic xxxxxx-releasenotes)" id="ptx1649725064918" xml:lang="en-us" xtrc="concept:1;3:49" >
    <title class="- topic/title ">Add a label when a specific class is matched</title>
    <shortdesc class="- topic/shortdesc ">Lorem Ipsum</shortdesc>
    <conbody class="- topic/body  concept/conbody ">
        
        <codeblock class="+ topic/pre pr-d/codeblock " id="codeblock_nxc_sjm_dtb" outputclass="collapse-folded">
            HTTP/1.1 200 OK
            Content-Type: application/json;charset=UTF-8
            {
            "id":"a7d67610-ceb5-4350-ba5a-746472c4f1f7",
            "schemas": [
            "urn:scim:schemas:core:1.0",
            "urn:scim:schemas:com_pingone:1.0" 
            ],
            "urn:scim:schemas:com_pingone:1.0": {
            "createTimeStamp":1429123454227,
            "accountId":"a6538050-412a-4bca-a44d-07deb4b073a8",
            "lastModifiedTimeStamp":1429123454227,
            "directoryId":"90b3dfe3-f8d0-45ad-8c04-047c88b03137",
            "state":"ACTIVE" 
            },
            "groups":[
            {
            "display":"Users",
            "value":"0b854f8d-a291-4e95-ad4b-68474a666e55" 
            }
            ]
            }
        </codeblock>
        
    </conbody>
</concept>
However, my XSLT doesn't seem to correctly target the class topic/pre or the pr-d/codeblock

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
    xmlns:table="http://dita-ot.sourceforge.net/ns/201007/dita-ot/table"
    xmlns:dita-ot="http://dita-ot.sourceforge.net/ns/201007/dita-ot"
    xmlns:dita2html="http://dita-ot.sourceforge.net/ns/200801/dita2html"
    xmlns:related-links="http://dita-ot.sourceforge.net/ns/200709/related-links"
    exclude-result-prefixes="#all">
    <xsl:template match="*[contains(@outputclass, 'collapse-folded')]">
        <xsl:choose>
            <xsl:when test="
                    *[contains(@class, ' topic/pre ')]
                    or *[contains(@class, ' pr-d/codeblock ')]
                    ">
                <br/>

                <span class="ft-expanding-block-link" style="color: red; font-weight: bold;">
                   Show code block
                </span>
            </xsl:when>
            <xsl:otherwise>
                <h1>CLASS DETECTION IS NOT WORKING</h1>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
Would you have any idea where I'm wrong?
------
Gaspard
gbv34
Posts: 105
Joined: Thu Jan 20, 2022 12:36 pm

Re: Can't match the topic/pre class

Post by gbv34 »

Hi folks!
I succeeded in matching the class. I had to target the whole class with the + sign:

Code: Select all

 <xsl:when test="@class, '+ topic/pre pr-d/codeblock '">
------
Gaspard
Radu
Posts: 9059
Joined: Fri Jul 09, 2004 5:18 pm

Re: Can't match the topic/pre class

Post by Radu »

Hi,

This match:

Code: Select all

<xsl:when test="@class, '+ topic/pre pr-d/codeblock '">
does not seem to make sense to me, it probably always evaluates as "true" as you have there a sequence of two nodes, an attribute and a literal string.
I would assume the initial template match should have looked like this:

Code: Select all

 <xsl:template match="*[contains(@outputclass, 'collapse-folded')][contains(@class, ' topic/pre ')]">
A DITA <codeblock> extends a <pre> so matching ' topic/pre ' is enough to match both cases. Also it's enough to match with contains 'topic/pre ', you do not need to add the "+ " and the entire class avalue in the contains clause.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
chrispitude
Posts: 907
Joined: Thu May 02, 2019 2:32 pm

Re: Can't match the topic/pre class

Post by chrispitude »

Hi gbv34,

We similarly insert headings for some <bodydiv> specialization elements:

Code: Select all

  <!-- Add our own <bodydiv>-specialization intro labels -->
  <xsl:template match="*[contains-token(@class, 'topic/bodydiv')]">
    <div>
      <xsl:call-template name="commonattributes"/>
      <xsl:call-template name="setid"/>
      <xsl:apply-templates select="." mode="add-heading"/>
      <xsl:apply-templates/>
    </div>
  </xsl:template>

  <!-- headings for <bodydiv> specializations -->
  <xsl:mode name="div-pre" on-no-match="deep-skip"/>  <!-- no heading if a match isn't found -->
  <xsl:template match="*[contains-token(@class, 'snps-d/description-section')]" mode="add-heading"><p class="topic/p"><strong>Description</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/arguments-section')]" mode="add-heading"><p class="topic/p"><strong>Arguments</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/command-group-section')]" mode="add-heading"><p class="topic/p"><strong>Command Group</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/gui-section')]" mode="add-heading"><p class="topic/p"><strong>Graphical Interface Description</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/example-section')]" mode="add-heading"><p class="topic/p"><strong>Examples</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/license-section')]" mode="add-heading"><p class="topic/p"><strong>Licenses</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/returns-section')]" mode="add-heading"><p class="topic/p"><strong>Returns</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/library-section')]" mode="add-heading"><p class="topic/p"><strong>Library</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/shortcut-section')]" mode="add-heading"><p class="topic/p"><strong>Shortcut</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/syntax-section')]" mode="add-heading"><p class="topic/p"><strong>Syntax</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/usageerrors-section')]" mode="add-heading"><p class="topic/p"><strong>Errors</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/datatypes-section')]" mode="add-heading"><p class="topic/p"><strong>Data Types</strong></p></xsl:template>
  <xsl:template match="*[contains-token(@class, 'snps-d/whatnext-section')]" mode="add-heading"><p class="topic/p"><strong>What Next</strong></p></xsl:template>
Note that I use some XSLT 3.0 features (contains-token() and <xsl:mode>).

Going forward, I will be replacing these HTML-inserted headings with CSS-inserted headings (in both PDF Chemistry and WebHelp).

Does the following template work for your case?

Code: Select all

<xsl:template match="*[contains(@class, ' topic/pre ')]
                      [contains(@outputclass, 'collapse-folded')]">
    <span class="ft-expanding-block-link" style="color: red; font-weight: bold;">
        <xsl:next-match/>
    </span>
</xsl:template>
<xsl:next-match/> calls whatever template that would have applied next in the precedence list (including templates that might be contributed from other plugins!), so it's a great way to play nice with others.
Post Reply