Re: [xsl] Flatten DITA conrefs

Subject: Re: [xsl] Flatten DITA conrefs
From: "Toshihiko Makita tmakita@xxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 12 Apr 2025 15:28:59 -0000
According to the DITA specification, following CASMessages.dita concept 
topic is valid even if the @id="AFM-L-R-CAI-Selected-Off-status" 
attribute is duplicated.

Only the concept/@id is defined as ID.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="cas-messages">
 \xA0\xA0\xA0 <title>CASMessages Title</title>
 \xA0\xA0\xA0 <conbody>
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <p><ph id="AFM-L-R-CAI-Selected-Off-status">Select off</ph></p>
 \xA0\xA0\xA0 </conbody>
 \xA0\xA0\xA0 <concept id="cas-messages-2">
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <title>CASMessages Title (2)</title>
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <conbody>
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <p><ph id="AFM-L-R-CAI-Selected-Off-status">Select off once 
more</ph></p>
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0 </conbody>
 \xA0\xA0\xA0 </concept>
</concept>

Toshihiko Makita
Antenna House Ina Branch

On 2025/04/12 4:22, 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
>
> \xA0 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
>
> <concept id="ConrefTest-GAC500-B-15-30-27-02A-131C-A">
>
> \xA0\xA0\xA0 <title>Conref Test</title>
>
> \xA0\xA0\xA0 <conbody>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <section>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <title>Possible Cause</title>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <p>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <ph
>
> conref="CASMessages.dita#cas-messages/AFM-L-R-CAI-Selected-Off-status"
>
> outputclass="cas-status"/>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 </p>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0 </section>
>
> \xA0\xA0\xA0 </conbody>
>
> </concept>
>
> Here is my XSLT. If the conref doesnC"BBt 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";
>
> xmlns:xs="http://www.w3.org/2001/XMLSchema";
>
> xmlns:cp="http://www.frameexpert.com/functions/cp";
>
> \xA0\xA0\xA0 exclude-result-prefixes="xs cp"
>
> \xA0\xA0\xA0 version="3.0" expand-text="yes">
>
> \xA0\xA0\xA0\xA0<xsl:output indent="yes"/>
>
> \xA0\xA0\xA0\xA0<xsl:template 
> match="entry/ph[matches(@conref,'CASMessages','i')=true()]">
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:sequence select="cp:flattenConref(current())"/>
>
> \xA0\xA0\xA0 </xsl:template>
>
> \xA0\xA0\xA0\xA0<xsl:mode on-no-match="shallow-copy"/>
>
> \xA0\xA0\xA0\xA0<xsl:function name="cp:flattenConref">
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:param name="ph"/>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <!-- Split the conref to get the target file. -->
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:variable name="conrefData" 
> select="tokenize($ph/@conref,'#')"/>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:choose>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <!-- Make sure there is a file and it is available on 
> disk. -->
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:when test="count($conrefData)=2">
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:variable name="file" 
> select="resolve-uri($conrefData[1],base-uri($ph))"/>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:choose>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:when test="doc-available($file)=true()">
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <!-- Get the target id from the conref. -->
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:variable name="id" 
> select="tokenize($conrefData[2],'/')[last()]"/>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:choose>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <!-- See if the target element exists. -->
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:when test="doc($file)//*[@id=$id]">
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <!-- Return the conref's value. -->
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <ph 
> outputclass="{$ph/@outputclass}"><xsl:sequence 
> select="doc($file)//*[@id=$id]/text()"/></ph>
>
> </xsl:when>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 </xsl:choose>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 </xsl:when>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <!-- The conref file does not exist; return the ph 
> element. -->
>
> <xsl:otherwise><xsl:sequence select="$ph"/></xsl:otherwise>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 </xsl:choose>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 </xsl:when>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <!-- No # anchor; return the ph element. -->
>
> <xsl:otherwise><xsl:sequence select="$ph"/></xsl:otherwise>
>
> \xA0\xA0\xA0\xA0\xA0\xA0\xA0 </xsl:choose>
>
> \xA0\xA0\xA0 </xsl:function>
>
> </xsl:stylesheet>
>
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/1528015> 
> (by email <>)

Current Thread