Friday, May 6, 2011

Replacing attribute value in XSLT

I am trying to perform an XSL Transformation. But an attribute replacement doesn't work. I have this XSL:

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

<xsl:output encoding="UTF-8"
doctype-public="-//WAPFORUM//DTD WML 1.1//EN"
doctype-system="http://www.wapforum.org/DTD/wml_1.1.xml"/>

<xsl:template match="/">

<wml xml:lang="da">
<card id="FrontPage" title="{head/title}">
Why doesn't the title get inserted?

<p id="changed">The server processed this Jan 1st. 2009.</p>
</card></wml>
</xsl:template></xsl:stylesheet>

And the XML that will be transformed is an XHTML 1.0 Transitional document. The document naturally contains a html/head/title element. I want the text content of the title element inserted into the title attribute of the card element:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>DMI - The weather on Faroe Islands</title>
(...)

I use PHP 5.2.0 and libxslt version 1.1.19.

From stackoverflow
  • Change your template match expression to /html:

    <xsl:template match="/html">
    
  • There is two problems:

    <xsl:template match="/">
      <wml xml:lang="da">
         <card id="FrontPage" title="{html/head/title}">
    

    The document root ("/") isn't the <html> element. It's before the <html> element.

    Additionally, as divo correctly points out, you are missing the XHTML namespace:

    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:x="http://www.w3.org/1999/xhtml"
      exclude-result-prefixes="x"
    >
    
      <xsl:output 
        encoding="UTF-8" 
        doctype-public="-//WAPFORUM//DTD WML 1.1//EN"
        doctype-system="http://www.wapforum.org/DTD/wml_1.1.xml"
      />
    
      <xsl:template match="/">
        <wml xml:lang="da">
          <card id="FrontPage" title="{x:html/x:head/x:title}">
            <p id="changed">The server processed this Jan 1st. 2009.</p>
          </card>
        </wml>
      </xsl:template>
    </xsl:stylesheet>
    
  • You are missing the html namespace declaration. Try the following:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:xhtml="http://www.w3.org/1999/xhtml">
    
      <xsl:output encoding="UTF-8"
                  doctype-public="-//WAPFORUM//DTD WML 1.1//EN"
                  doctype-system="http://www.wapforum.org/DTD/wml_1.1.xml"
                  indent="yes"/>
    
      <xsl:template match="/">
    
        <wml xml:lang="da">
          <card id="FrontPage" title="{xhtml:html/xhtml:head/xhtml:title}">
            <p id="changed">The server processed this Jan 1st. 2009.</p>
          </card>
        </wml>
      </xsl:template>
    </xsl:stylesheet>
    

    Note that you may change the prefix from xhtml to anything shorter that you like.

    There has been another smaller problem also (which is probably based on a common misunderstanding): / means the document root which is not the same as the top-most node in the document (html). The top-most node is often called "root node" which is not correct, i.e. / does not match the top-most node. Therefore xhtml:html has to be added to the XPath expression.

    Tomalak : +1 for spotting the namespace problem.

0 comments:

Post a Comment