Home > Back-end >  How do I add a header to HTML being transformed by an XSLT stylesheet?
How do I add a header to HTML being transformed by an XSLT stylesheet?

Time:10-31

I have a stylesheet that is successfully transforming some XML data.

(The XML data transformation is irrelevant to the question and has been removed in the example)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns="http://www.w3.org/1999/xhtml" version="1.0">
<xsl:output doctype-system="about:legacy-compat" method="html" />
<xsl:template match="/contact:contact">
<html> 

  <head>
    <title>My Title</title>
    <xsl:copy-of select="document('../header.xml')" />
  </head> 

  <body id="page-top" class="modern">
[not relevant]
  </body>
</html>
</xsl:template>
</xsl:stylesheet>

The stylesheet includes the following line, which we want to use to insert a header into the output. We have full control over the header, and the header is well formed XML.

    <xsl:copy-of select="document('../header.xml')" />

The header consists of a head tag with nodes as content, and we want our nodes to be inserted into our final output.

<?xml version="1.0" encoding="UTF-8"?>
<head xmlns="http://www.w3.org/1999/xhtml">
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
  <meta name="description" content="" />
  <meta name="author" content="" />
</head>

Right now we are close, but our root head element is included twice:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>My Title</title>
    <head>
      <meta charset="utf-8"></meta>
      <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"></meta>
      <meta name="description" content=""></meta>
      <meta name="author" content=""></meta>
    </head>
  </head>
  <body id="page-top" class="modern">
  </body>
</html>

What modification do we make to this line so that just the children of the root node head are included, without the root node itself:

    <xsl:copy-of select="document('../header.xml')" />

Resulting in output that looks like this:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>My Title</title>
    <meta charset="utf-8"></meta>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"></meta>
    <meta name="description" content=""></meta>
    <meta name="author" content=""></meta>
  </head>
  <body id="page-top" class="modern">
  </body>
</html>

(Similar questions have been asked many times, most answers relate to custom behaviour of the XSLT processor. I need standards compliant XSLT that will work in a modern browser).

CodePudding user response:

Try:

<xsl:copy-of select="document('../header.xml')/*/*" />

Strictly speaking, you should bind the http://www.w3.org/1999/xhtml namespace to a prefix, then use it - e.g.

<xsl:copy-of select="document('../header.xml')/x:head/*" />

but I am not sure it's worth the bother.

  • Related