|
Subject: Re: [xsl] Flatten DITA conrefs From: "rick@xxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Sun, 13 Apr 2025 00:30:59 -0000 |
Thank you for the updated code. It was a mistake to return an empty sequence
in my original code. Yours makes sense. Thank you also for the feedback on the
Boolean functions.
From: Michael Kay michaelkay90@xxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Sent: Saturday, April 12, 2025 3:51 AM
To: xsl-list <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject: Re: [xsl] Flatten DITA conrefs
>bJavaScript: The Good Partsb and his counsel was to be as explicit as
possible when programming so I like to use true() and false() when making
comparisons.
There's something to be said for avoiding reliance on "effective boolean
value" conversions, but when you're testing the result of a function like
matches() or doc-available() that always returns a boolean, it makes very
little sense. You wouldn't (I hope) write `test="(@x = 2) = true()"`.
I would encourage you to declare the parameter type and result type of the
function. (Both as="element(ph)", I think). This might point out that when the
innermost xsl:when condition is false, there is no xsl:otherwise so you are
returning an empty sequence. I don't know if that's what you intended.
I would be inclined to write
<xsl:function name="cp:flattenConref" as="element(ph)">
<xsl:param name="ph" as="element(ph)"/>
<!-- Split the conref to get the target file. -->
<xsl:variable name="conrefData" select="tokenize($ph/@conref,'#')"/>
<xsl:variable name="result" as="element(ph)?">
<!-- Make sure there is a file and it is available on disk. -->
<xsl:if test="count($conrefData)=2">
<xsl:variable name="file"
select="resolve-uri($conrefData[1],base-uri($ph))"/>
<xsl:if test="doc-available($file)=true()">
<!-- Get the target id from the conref. -->
<xsl:variable name="id"
select="tokenize($conrefData[2],'/')[last()]"/>
<xsl:variable name="target"
select="doc($file)//*[@id=$id]"/>
<!-- See if the target element exists. -->
<xsl:if test="exists($target)">
<!-- Return the conref's value. -->
<ph
outputclass="{$ph/@outputclass}"><xsl:sequence select="$target/text()"/></ph>
</xsl:if>>
</xsl:if>
</xsl:variable>
<xsl:sequence select="($result, $ph)[1]"/>
</xsl:function>
From: Martin Honnen martin.honnen@xxxxxx <mailto:martin.honnen@xxxxxx>
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx
<mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> >
Sent: Friday, April 11, 2025 6:07 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx <mailto:xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject: Re: [xsl] Flatten DITA conrefs
On 11/04/2025 21:21, rick@xxxxxxxxxxxxxx <mailto:rick@xxxxxxxxxxxxxx> wrote:
Hi All,
I am working with a DITA transformation and I want to flatten some conrefs. I
have created a function to do this, and it is working, but I am looking for
feedback to see if there is a better approach. Here is my XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE concept
PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="ConrefTest-GAC500-B-15-30-27-02A-131C-A">
<title>Conref Test</title>
<conbody>
<section>
<title>Possible Cause</title>
<p>
<ph
conref="CASMessages.dita#cas-messages/AFM-L-R-CAI-Selected-Of
f-status"
outputclass="cas-status"/>
</p>
</section>
</conbody>
</concept>
Here is my XSLT. If the conref doesnbt resolve, I am just passing the parent
element through as is.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl= <http://www.w3.org/1999/XSL/Transform>
"http://www.w3.org/1999/XSL/Transform"
xmlns:xs= <http://www.w3.org/2001/XMLSchema>
"http://www.w3.org/2001/XMLSchema"
xmlns:cp= <http://www.frameexpert.com/functions/cp>
"http://www.frameexpert.com/functions/cp"
exclude-result-prefixes="xs cp"
version="3.0" expand-text="yes">
<xsl:output indent="yes"/>
<xsl:template
match="entry/ph[matches(@conref,'CASMessages','i')=true()]">
<xsl:sequence select="cp:flattenConref(current())"/>
</xsl:template>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:function name="cp:flattenConref">
<xsl:param name="ph"/>
<!-- Split the conref to get the target file. -->
<xsl:variable name="conrefData" select="tokenize($ph/@conref,'#')"/>
<xsl:choose>
<!-- Make sure there is a file and it is available on disk. -->
<xsl:when test="count($conrefData)=2">
<xsl:variable name="file"
select="resolve-uri($conrefData[1],base-uri($ph))"/>
<xsl:choose>
<xsl:when test="doc-available($file)=true()">
<!-- Get the target id from the conref. -->
<xsl:variable name="id"
select="tokenize($conrefData[2],'/')[last()]"/>
<xsl:choose>
<!-- See if the target element exists. -->
<xsl:when test="doc($file)//*[@id=$id]">
<!-- Return the conref's value. -->
<ph
outputclass="{$ph/@outputclass}"><xsl:sequence
select="doc($file)//*[@id=$id]/text()"/></ph>
</xsl:when>
</xsl:choose>
</xsl:when>
<!-- The conref file does not exist; return the ph
element. -->
<xsl:otherwise><xsl:sequence
select="$ph"/></xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- No # anchor; return the ph element. -->
<xsl:otherwise><xsl:sequence select="$ph"/></xsl:otherwise>
</xsl:choose>
</xsl:function>
</xsl:stylesheet>
Two small comments, I never get why people use a comparison to true or false,
I would just go with e.g.
xsl:template match="entry/ph[matches(@conref,'CASMessages','i')]"
and
xsl:when test="doc-available($file)"
And I wonder whether DITA sets up the id attribute as a DTD ID or schema xs:ID
so that instead of
doc($file)//*[@id=$id]
you could use e.g.
id($id, doc($file))
XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/612310> (by
email)
XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/3500899> (by
email)
XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/612310> (by
email <> )
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] Flatten DITA conrefs, Michael Kay michaelk | Thread | Re: [xsl] Flatten DITA conrefs, Toshihiko Makita tma |
| Re: [xsl] Flatten DITA conrefs, Paul Tyson phtyson@x | Date | [xsl] I desire this function: subst, Roger L Costello cos |
| Month |