XSLT simplified stylesheet with xsl:attribute-set element

2.4k views Asked by At

I'm trying to use the <xsl:attribute-set> in my xsl document but I keep getting error messages:

  • compilation error: line 47 element attribute-set
  • element attribute-set only allowed as child of stylesheet

I've also checked the W3Schools website's explanation on XSLT attribute-sets and found out that:

Must be child of <xsl:stylesheet> or <xsl:transform>.

I don't understand what this means, can anyone explain?

If you need more information about my documents, WAMP server set up please comment below.

The first two lines of my XSL document is:

<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">

I have no idea what they do, just that without it, my XSL will not work.

I am basically transforming my XML into HTML using this XSL file. The whole process is done by PHP:

# START XSLT
$xslt = new XSLTProcessor(); 
$XSL = new DOMDocument(); 
$XSL->load('hello.xsl'); 
$xslt->importStylesheet($XSL); 

# LOAD XML FILE 
$XML = new DOMDocument();
$XML->load('hello.xml');

#PRINT 
print $xslt->transformToXML($XML);
3

There are 3 answers

1
Michael Kay On BEST ANSWER

You are using the very rarely-seen "literal result element as stylesheet" facility, also known as a "simplified stylesheet", in which the xsl:stylesheet element and the outermost xsl:template are implicit. Your problem illustrates why this facility is so rarely used - it quickly runs out of steam. Because there is no xsl:stylesheet element, none of the usual children of xsl:stylesheet can be present, and this includes declarations of attribute sets.

Change your code to wrap it in an explicit xsl:stylesheet and xsl:template match="/". Then add an xsl:attribute-set at the same level as the xsl:template.

2
Lachlan Roche On

The following was written before the start of XSLT was added to the question. It does not address the literal result element as stylesheet nature of the problem. Michael Kay's answer does.

An xsl:attribute-set must be a child element of your xsl:stylesheet element, which is the root element of the XSLT. This is the same as for xsl:output or xsl:template.

The standard describes these elements as being in the "top-level-element" category.

w3schools.com says this in several ways:

  • ELMENT is a top-level element.
  • Must be child of <xsl:stylesheet> or <xsl:transform>
  • ELEMENT is a top-level element, and must appear as a child node of <xsl:stylesheet> or <xsl:transform>

example

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>

    <xsl:attribute-set name="body-attr">
        <xsl:attribute name="color">red</xsl:attribute>
    </xsl:attribute-set>

    <xsl:template match="/">
        <xsl:element name="result" use-attribute-sets="body-attr">
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>
0
Paul Sweatte On

Another way this would work with the simplified syntax would be to move the xmlns off of the html tag, then inline the source file via the document function:

<?xml version="1.0" encoding="UTF-8"?>
 <section
  xsl:version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns=""
 >

    <blockquote>
        <xsl:for-each select="document('movies.xml')//processing-instruction()[contains(., '2014')]">
            <p><xsl:value-of select="concat( local-name(),' ', current() )"/></p>

            <a href="{substring-before(document('movies.xml')//processing-instruction(),',')}">
                <input type="button" value="Stream {local-name()}"/>
            </a>

            <a href="{substring-after(document('movies.xml')//processing-instruction(),',')}">
                <input type="button" value="{local-name()} Soundtrack"/>                    
            </a>

        </xsl:for-each>            
    </blockquote>

 </section>

Then include it:

<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
    <include href="simple.xsl"/>
    <attribute-set name="foo"></attribute-set>
    <apply-templates/>
</stylesheet>

In turn this means that the only useful way to initiate the transformation is to supply a document node as the initial match selection, to be matched by the implicit match="/" template rule using the unnamed mode.

References