1
Preamble

In the usecase I try to solve, I could have in each document different speakers (with different first names, last names, nicknames, honorific titles…). The information related to each speaker are not universal and should still related to an xml document. So, we could not store this information in the xslt stylesheet.

The goal

So, the goal is just to store variables in the xml and then reuse it each time we need it.

Minimal Wworking Example

This is the xml file I make:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xtension-element-prefixes="dyn">
    <xsl:variable name="socrate"> <!-- Variable declaration of the speaker Socrate -->
        <longname>Socrate</longname>
        <shortname>Soc</shortname>
    </xsl:variable>


    <body>
        <speaker><xsl:copy select="$socrate" /></speaker>
    </body>

</xsl:stylesheet>

The XSLT stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xtension-element-prefixes="dyn">
<xsl:output method="html" indent="yes"/>

    <xsl:template match="speaker">
        <span class="speaker">
            <xsl:value-of select="speaker" />
        </span>
    </xsl:template>

</xsl:stylesheet>

The result (using xsltproc stylesheet.xslt example.xml > test.html):


    
        Socrate
        Soc
    


    
        <span class="speaker"></span> <!-- ← This is the relevant line -->
    


As you see, the call to the variable $socrate is just completely ignored.

The question

Is it possible to declare variables and reusite with the above way or with any other way? then how?

fauve
  • 226
  • 1
  • 10
  • It is possible to create an XML that contains a "dictionary" of terms and then various references to those terms - so that you would only need to define "Socrates" once, but could refer to it many times, without repeating the data. But you cannot accomplish this using the XSLT language within the input XML. You need to use some other method. What is the actual problem you are trying to solve by this? – michael.hor257k Mar 20 '23 at 05:36

2 Answers2

2

It seems that your question is more about XML design than about XSLT. Consider the folllowing simplified example:

XML

<root>
    <dictionary>
        <entry key="1">Adam Smith</entry>
        <entry key="2">Betty Blue</entry>
        <entry key="3">Cecil Crow</entry>
    </dictionary>
    <text>Said <reference ref="1"/> to <reference ref="2"/>: "What did you say to <reference ref="3"/>?"</text>
</root>

XSLT 1.0

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

<xsl:key name="dict" match="entry" use="@key"/>

<xsl:template match="/root">
    <expanded_text>
        <xsl:apply-templates select="text"/>
    </expanded_text>
</xsl:template>

<xsl:template match="reference">
    <xsl:value-of select="key('dict', @ref)"/>
</xsl:template>
 
</xsl:stylesheet>

Result

<?xml version="1.0" encoding="UTF-8"?>
<expanded_text>Said Adam Smith to Betty Blue: "What did you say to Cecil Crow?"</expanded_text>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
2

You want xsl:copy-of, not xsl:copy. The xsl:copy instruction does a shallow copy - $socrate is a document node, so you are copying the document node without copying its children.

Compounding this, the xsl:copy instruction in XSLT versions prior to 3.0 does not have a select attribute, so the result is going to depend on what XSLT processor you are using.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164