[xsl] Algorithm for setting a variable number of attributes

Subject: [xsl] Algorithm for setting a variable number of attributes
From: "rick@xxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 2 Aug 2022 17:47:46 -0000
Hello All,

 

I have this as my input:

 

<?xml version="1.0" encoding="UTF-8"?>

<root>

    <subtask>SUBTASK 25-31-04-714-080 - (20130315)</subtask>

</root>

 

And this is my desired output:

 

<?xml version="1.0" encoding="UTF-8"?>

<root>

    <subtask chapnbr="25" sectnbr="31" subnbr="04" func="714" seq="080"
revdate="20130315"/>

</root>

 

I am using a function to parse the input and get it down to a tokenized
sequence. Sometimes the input may not have all of the same positions of
data; for example, it may be:

 

<subtask>SUBTASK 25-31-04</subtask>

 

I can use a series of <xsl:if> statements to add the appropriate attribute
values based on count($attributes), but that makes the <xsl:template
match="subtask"> a bit busy. I am wondering if there is a better way to do
this. For example, can I add the attributes to the element inside my
function? Here is my XSLT. Thank you.

 

<?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:math="http://www.w3.org/2005/xpath-functions/math";

    xmlns:rq="http://www.frameexpert.com/functions";

    exclude-result-prefixes="xs math rq"

    version="3.0" expand-text="yes">

    

    <xsl:output indent="yes"/>

    

    <xsl:template match="/">

        <root>

            <xsl:apply-templates/>

        </root>

    </xsl:template>

    

    <xsl:template match="subtask">

        <xsl:copy>

            <xsl:variable name="attributes"
select="rq:getSubtaskAttributes(.)"/>

            <xsl:message>{$attributes}</xsl:message>

        </xsl:copy>

    </xsl:template>

    

    <xsl:function name="rq:getSubtaskAttributes">

        <xsl:param name="context"/>

        <xsl:variable name="variable1"
select="replace($context,'[^-\d]+','')"/>

        <xsl:sequence select="tokenize($variable1,'-')"/>

    </xsl:function>

    

</xsl:stylesheet>

Current Thread