Store and use variable inside an XML file

350 views Asked by At
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?

2

There are 2 answers

0
michael.hor257k On BEST ANSWER

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>
0
Michael Kay On

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.