I have a docBook 4.4 XML file which is a user guide. I can use the (Maven) tools to convert that to HTML, PDF no problem. The problem i have is to insert an small HTML code snippet into the resulting HTML file.
I would like to add the following HTML snippet:
<xsl:template name="xxxxxxx">
<img src="images/pdfdoc.gif">PDF</img>
</xsl:template>
The resulting HTML code looks like this:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Title</title>
<link rel="stylesheet" type="text/css" href="./hilfeKMV.css">
<meta name="generator" content="DocBook XSL Stylesheets V1.76.0">
<meta name="date" content="10/12/2011">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084"
alink="#0000FF">
<div lang="de" class="book"
title="Title">
<div class="titlepage">
<div>
<div>
<h1 class="title">
<a name="d0e1"></a>title
</h1>
</div>
</div>
<hr>
</div>
<div class="toc">
<p>
<b>TOC</b>
</p>
I would like to insert the HTML snippet before the <div class="toc">...So the question is how to solve this? I'm using docbook 1.76.0
I think there must be something like the following to solve that but i don't know how to set call-template etc. ?
<xsl:template name="xxxxxxx">
<xsl:variable name="top-anchor">
<xsl:call-template name="object.id">
<xsl:with-param name="object" select="/*[1]"/>
</xsl:call-template>
</xsl:variable>
<img src="images/pdfdoc.gif">PDF</img>
</xsl:template>
The <div class="toc"> element is generated by the template named "make.toc", which is called by "division.toc" (in autotoc.xsl). In order to output something immediately before this <div>, you can override the "division.toc" template in your customization layer. Just copy the original template and add your code, like this:
<xsl:template name="division.toc">
<xsl:param name="toc-context" select="."/>
<xsl:param name="toc.title.p" select="true()"/>
<img src="images/pdfdoc.gif" alt="PDF"/> <!-- Your stuff here -->
<xsl:call-template name="make.toc">
...
...
</xsl:call-template>
</xsl:template>
I have found the correct location to insert the code i need.
In the titlepage.templates.xsl file i found the correct solution. I just taken the snippet from the titlepage.templates.xsl and enhanced it like the following:
<xsl:template name="book.titlepage.separator">
<div class="subsubtile">
<div class="pdflink">
<a href="./xxxx.pdf" title="Hilfeseite als PDF-Dokument">
<img src="images/pdfdoc.gif" border="0" alt="Hilfeseite als PDF-Dokument" />
<br />
PDF
</a>
</div>
</div>
<hr/>
</xsl:template>
Related
I'm new to XSLT and I can't understand why the root get processed twice (at least this is my interpretation of this output).
EDIT: (I'm using Saxon-HE with XSLT 2.0) but also tested with several online processes, getting always the same result.
XSLT file
<?xml version="1.0" encoding="UTF-8"?>
<!-- XResume.xsl: resume.xml ==> resume.xhtml -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="https://github.com/IME-SE8/XResume">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<head>
<meta charset="utf-8" />
<meta lang="en" />
<meta name="description" content="Personal Resume and Portfolio" />
<title><xsl:value-of select="resume/personalInformation/name/attribute::shortForm" /> Website</title>
</head>
<body>
<xsl:apply-templates select="resume"/>
</body>
</html>
</xsl:template>
<xsl:template match="resume">
<div class="resume">
<div class="header">
<div class="name"><xsl:value-of select="personalInformation/name" /></div>
<div class="contacts">
<xsl:for-each select="personalInformation/contact">
<div class="contactInformation">
<p><xsl:value-of select="organization" /></p>
<p><xsl:value-of select="address" /></p>
<p><xsl:value-of select="phoneNumber" /></p>
<p><xsl:value-of select="email" /></p>
</div>
</xsl:for-each>
</div>
</div>
<div class="sections">
<xsl:apply-templates />
</div>
</div>
</xsl:template>
<xsl:template match="interests"></xsl:template>
<xsl:template match="education"></xsl:template>
<xsl:template match="skills"></xsl:template>
<xsl:template match="experiences"></xsl:template>
<xsl:template match="projects"></xsl:template>
<xsl:template match="awards"></xsl:template>
</xsl:stylesheet>
XML file
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl"
href="https://github.com/IME-SE8/XResume/master/XResume.xsl"?>
<resume
xmlns="https://github.com/IME-SE8/XResume"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://github.com/IME-SE8/XResume XResume.xsd">
<personalInformation>
<name first="John" last="Doe" shortForm="JD">John Doe</name>
<contact type="institutional">
<organization>StackOverflow Institute of Technology</organization>
<address>Internet</address>
<phoneNumber>+1 (666) 666-9999</phoneNumber>
<email>john#d.oe</email>
</contact>
</personalInformation>
<interests>
<interest>Q and A</interest>
<interest>XSLT</interest>
</interests>
<education></education>
<skills></skills>
<experiences></experiences>
<projects></projects>
<awards></awards>
</resume>
HTML output
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta lang="en">
<meta name="description" content="Personal Resume and Portfolio">
<title>JD Website</title>
</head>
<body>
<div class="resume">
<div class="header">
<div class="name">John Doe</div>
<div class="contacts">
<div class="contactInformation">
<p>StackOverflow Institute of Technology</p>
<p>Internet</p>
<p>+1 (666) 666-9999</p>
<p>john#d.oe</p>
</div>
</div>
</div>
<div class="sections">
John Doe
StackOverflow Institute of Technology
Internet
+1 (666) 666-9999
john#d.oe
</div>
</div>
</body>
</html>
(yes, with that amount of blank lines)
The output header div is perfectly fine, but inside the sections div that apply-templates renders all the information in the div header again but without the HTML tags.
Is there any XSLT processing detail am I missing? Does the template match sets the context in a way that the matched element is now considered a root or something like that?
The problem is here:
<div class="sections">
<xsl:apply-templates />
</div>
This applies templates to all child nodes of the current node (resume), including the personalInformation element.
As there is no matching template specified for personalInformation, the builtin XSLT templates are used by the XSLT processor and applying them results in outputting the concatenation of all descendent text-nodes of the personalInformation element.
Solution:
Replace:
<div class="sections">
<xsl:apply-templates />
</div>
with:
<div class="sections">
<xsl:apply-templates select="*[not(self::personalInformation)]" />
</div>
The result of the transformation now doesn't contain the noted problematic output:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta lang="en">
<meta name="description" content="Personal Resume and Portfolio">
<title>JD Website</title>
</head>
<body>
<div class="resume">
<div class="header">
<div class="name">John Doe</div>
<div class="contacts">
<div class="contactInformation">
<p>StackOverflow Institute of Technology</p>
<p>Internet</p>
<p>+1 (666) 666-9999</p>
<p>john#d.oe</p>
</div>
</div>
</div>
<div class="sections"></div>
</div>
</body>
</html>
You haven't supplied an expected output, so I will guess at your intended outcome. Here is an XSLT 2.0 solution. If you need XSLT 1.0, please comment, and I can add. But just remember that if your transform engine is the browser, you have no excuse not to use XSLT 2.0. (Refer Saxon CE).
XSLT 2.0 Solution
This XSLT 2.0 stylesheet ...
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:r="https://github.com/IME-SE8/XResume"
exclude-result-prefixes="r"
version="2.0">
<xsl:output method="html" version="5" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<html>
<head>
<meta lang="en" />
<meta name="description" content="Personal Resume and Portfolio" />
<title><xsl:value-of select="r:resume/r:personalInformation/r:name/#shortForm" /> Website</title>
</head>
<body>
<xsl:apply-templates select="r:resume"/>
</body>
</html>
</xsl:template>
<xsl:template match="r:resume">
<div class="resume">
<div class="header">
<div class="name"><xsl:value-of select="r:personalInformation/r:name" /></div>
<div class="contacts">
<xsl:apply-templates select="r:personalInformation/r:contact" />
</div>
</div>
<div class="sections">
<xsl:apply-templates select="* except r:personalInformation" />
</div>
</div>
</xsl:template>
<xsl:template match="r:contact">
<div class="contactInformation">
<xsl:apply-templates />
</div>
</xsl:template>
<xsl:template match="r:organization|r:address|r:phoneNumber|r:email">
<p><xsl:value-of select="." /></p>
</xsl:template>
<xsl:template match="r:education|r:skills|r:experiences|r:projects|r:awards">
<h2><xsl:value-of select="local-name()" /></h2>
<p><xsl:value-of select="." /></p>
</xsl:template>
<xsl:template match="r:interests">
<h2>interests</h2>
<ul>
<xsl:apply-templates />
</ul>
</xsl:template>
<xsl:template match="r:interest">
<li>
<xsl:value-of select="." />
</li>
</xsl:template>
<xsl:template match="*" />
</xsl:transform>
... when applied to this input document ...
<resume
xmlns="https://github.com/IME-SE8/XResume"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://github.com/IME-SE8/XResume XResume.xsd">
<personalInformation>
<name first="John" last="Doe" shortForm="JD">John Doe</name>
<contact type="institutional">
<organization>StackOverflow Institute of Technology</organization>
<address>Internet</address>
<phoneNumber>+1 (666) 666-9999</phoneNumber>
<email>john#d.oe</email>
</contact>
</personalInformation>
<interests>
<interest>Q and A</interest>
<interest>XSLT</interest>
</interests>
<education></education>
<skills></skills>
<experiences></experiences>
<projects></projects>
<awards></awards>
</resume>
... will yield this output html page ....
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta lang="en">
<meta name="description" content="Personal Resume and Portfolio">
<title>JD Website</title>
</head>
<body>
<div class="resume">
<div class="header">
<div class="name">John Doe</div>
<div class="contacts">
<div class="contactInformation">
<p>StackOverflow Institute of Technology</p>
<p>Internet</p>
<p>+1 (666) 666-9999</p>
<p>john#d.oe</p>
</div>
</div>
</div>
<div class="sections">
<h2>interests</h2>
<ul>
<li>Q and A</li>
<li>XSLT</li>
</ul>
<h2>education</h2>
<p></p>
<h2>skills</h2>
<p></p>
<h2>experiences</h2>
<p></p>
<h2>projects</h2>
<p></p>
<h2>awards</h2>
<p></p>
</div>
</div>
</body>
</html>
Explanation: Why were you getting root processed twice
In short because your <div class="sections"><xsl:apply-templates /></div> instruction did not specify a select attribute. The default selection applied, which was at that point the document root.
All the elements in your source document are in a namespace, but your stylesheet is written to process elements in no namespace. Welcome to the club, and join the 10m other people who have fallen into this trap. Essentially, you resume elements don't match the match="resume" template, so the default template kicks in, and this outputs the raw text with no tags. For the solution, search on "XSLT default namespace" and choose any one of about 1000 answers.
On re-reading, I see that you've used xpath-default-namespace="https://github.com/IME-SE8/XResume", which should fix the problem if you are using an XSLT 2.0 processor, or trigger an error if you're using an XSLT 1.0 processor. So it might be useful (actually, it's always useful) to tell us what processor you are using and how you are running it.
In my source XML, the less-than sign is represented as <, but in the output (html, as alt-text) it is represented as the < sign, which causes problems in post-processing.
I'm using saxon655 with this command line:
java -cp saxon655/saxon.jar com.icl.saxon.StyleSheet test.xml test.xsl
This really doesn't make sense to me. Here are the details:
The DocBook XML:
<chapter xmlns="http://docbook.org/ns/docbook">
<info><title>The Chapter</title></info>
<para>
<informalequation>
<mediaobject>
<imageobject>
<imagedata fileref="images/g0589.png" />
</imageobject>
<textobject role="tex"><phrase>|z_ s-z_ t|<r</phrase></textobject>
</mediaobject>
</informalequation>
</para>
</chapter>
The XSLT. If you copy this, change the path the docbook stylesheets.
<xsl:stylesheet version="1.0"
xmlns:d="http://docbook.org/ns/docbook"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="/path/to/docbook/xsl-1.78.1/html/docbook.xsl" />
<xsl:template match="d:mediaobject/d:imageobject/d:imagedata">
<xsl:element name="img">
<xsl:attribute name="alt">
<xsl:value-of select="../../d:textobject[#role='tex']/d:phrase" />
</xsl:attribute>
<xsl:attribute name="src">
<xsl:value-of select="#fileref" />
</xsl:attribute>
</xsl:element>
<xsl:apply-templates />
</xsl:template>
</xsl:stylesheet>
And the resulting HTML portion:
<div class="informalequation">
<div class="mediaobject">
<img alt="|z_ s-z_ t|<r" src="images/g0589.png"></div>
</div>
Am I doing something wrong?
As far as the W3C HTML validator says, for text/html the output is fine, I created a minimal HTML 4.01 document with the markup you have at http://home.arcor.de/martin.honnen/html/test2015040301.html, it has the content
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>img alt attribute test</title>
</head>
<body>
<div class="informalequation">
<div class="mediaobject">
<img alt="|z_ s-z_ t|<r" src="images/g0589.png"></div>
</div>
</body>
</html>
and the validator says (http://validator.w3.org/check?uri=http%3A%2F%2Fhome.arcor.de%2Fmartin.honnen%2Fhtml%2Ftest2015040301.html&charset=%28detect+automatically%29&doctype=Inline&group=0) "This document was successfully checked as HTML 4.01 Strict!". So I think Saxon is creating correct HTML, I don't know how you post-process the result of the XSLT transformation but an HTML or SGML parser should do fine with it.
With an XML output (method="xml") Saxon does escape the less than in the attribute value.
I have a series of nodes that are direct child nodes to a parent I want to loop over those nodes but have them wrapped in 'groups' of 4... I'm probably not wording this very clearly so this might help;
<span class="child01">#nodename</span>
<span class="child02">#nodename</span>
<span class="child03">#nodename</span>
<span class="child04">#nodename</span>
<span class="child05">#nodename</span>
<span class="child06">#nodename</span>
<span class="child07">#nodename</span>
<span class="child08">#nodename</span>
..
<span class="child32">#nodename</span>
<span class="child33">#nodename</span>
..and so on
Goal
<div class="group">
<span class="child01">#nodename</span>
<span class="child02">#nodename</span>
<span class="child03">#nodename</span>
<span class="child04">#nodename</span>
</div>
<div class="group">
<span class="child05">#nodename</span>
<span class="child06">#nodename</span>
<span class="child07">#nodename</span>
<span class="child08">#nodename</span>
</div>
<div class="group">
..
<span class="child32">#nodename</span>
</div>
<div class="group">
<span class="child33">#nodename</span>
..and so on
I have tried variations on this idea - wrapping the lot in the open and closing group tags and every fourth loop drop in a new close / open pair
<div class="group">
<xsl:for-each select="$currentPage/*">
<span>
<xsl:value-of select="#nodeName" />
</span>
<!--
=============================================================
After very 4th item
=============================================================
-->
<xsl:if test="position() mod 4 = 0">
<xsl:text></div><div class="page"></xsl:text>
</xsl:if>
</xsl:for-each>
</div>
But essentially it seems XSLT won't let me start with a closing unmatched tag
The clkoset solution I ahve found so far is a 'fix' in jquery Wrapping a div around every three divs but I would rather not rely on javascript to format the page.
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pNumCols" select="3"/>
<xsl:template match="/*">
<xsl:apply-templates select="span[position() mod $pNumCols = 1]"/>
</xsl:template>
<xsl:template match="span">
<div>
<xsl:copy-of select=
".|following-sibling::span[not(position() > $pNumCols -1)]"/>
</div>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<t>
<span class="child01">#nodename</span>
<span class="child02">#nodename</span>
<span class="child03">#nodename</span>
<span class="child04">#nodename</span>
<span class="child05">#nodename</span>
<span class="child06">#nodename</span>
<span class="child07">#nodename</span>
<span class="child08">#nodename</span> ..
<span class="child32">#nodename</span>
<span class="child33">#nodename</span>
</t>
produces the wanted result:
<div>
<span class="child01">#nodename</span>
<span class="child02">#nodename</span>
<span class="child03">#nodename</span>
</div>
<div>
<span class="child04">#nodename</span>
<span class="child05">#nodename</span>
<span class="child06">#nodename</span>
</div>
<div>
<span class="child07">#nodename</span>
<span class="child08">#nodename</span>
<span class="child32">#nodename</span>
</div>
<div>
<span class="child33">#nodename</span>
</div>
If like me you need to transform the source elements that are being divided by position, use xsl:for-each instead of xsl:copy:
<xsl:template match="span">
<ol>
<xsl:for-each select=".|following-sibling::span[not(position() > $pNumCols -1)]"/>
<li><xsl:value-of select="./text()"/></li>
</xsl:for-each>
</ol>
</xsl:template>
Faced by the same problem, that is wanting to output
<div class="container">
<div class="row">
<div class="col">...</div>
<div class="col"/>...</div>
</div>
<div class="row">
...
</div>
</div>
from a CXML (Collection XML) file (http://gallery.clipflair.net/collection/activities.cxml - the data behind the PivotViewer display at http://gallery.clipflair.net/activity)
I coined up the following, based on other suggestions here, but using "mode" attribute of "template" and "apply-templates" XSL tags instead which make it cleaner I believe:
<?xml version="1.0" encoding="UTF-8"?>
<?altova_samplexml http://gallery.clipflair.net/collection/activities.cxml?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cxml="http://schemas.microsoft.com/collection/metadata/2009"
exclude-result-prefixes="cxml"
>
<xsl:output method="html" version="4.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="COLUMNS" select="2"/>
<!-- ########################### -->
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>ClipFlair Activities</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<!-- ########################### -->
<xsl:template match="cxml:Collection">
<div class="container">
<xsl:apply-templates/>
</div>
</xsl:template>
<!-- ########################### -->
<xsl:template match="cxml:Items">
<xsl:apply-templates select="cxml:Item[position() mod $COLUMNS = 1]" mode="row"/>
</xsl:template>
<!-- ########################### -->
<xsl:template match="cxml:Item" mode="row">
<div class="row">
<div>----------</div>
<xsl:apply-templates select=".|following-sibling::cxml:Item[position() < $COLUMNS]" mode="col"/>
</div>
</xsl:template>
<xsl:template match="cxml:Item" mode="col">
<xsl:variable name="URL" select="#Href"/>
<xsl:variable name="FILENAME" select="cxml:Facets/cxml:Facet[#Name='Filename']/cxml:String/#Value"/>
<div class="col">
<xsl:value-of select="$FILENAME"/> --- <xsl:value-of select="$URL"/>
</div>
</xsl:template>
<!-- ########################### -->
<xsl:template match="*">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()|#*">
</xsl:template>
</xsl:stylesheet>
the output from the above when run in Altova XMLSpy tool (note that it uses altova_samplexml processor instruction to find the XML data) is:
2DaysInParis-OpenActivity-CapRev-FR-EN.clipflair --- http://studio.clipflair.net/?activity=2DaysInParis-OpenActivity-CapRev-FR-EN.clipflair
Abu_Dukhan-CapRev-A1-AR.clipflair --- http://studio.clipflair.net/?activity=Abu_Dukhan-CapRev-A1-AR.clipflair
----------
AFarewellToArms-RevCap-C2-EN.clipflair --- http://studio.clipflair.net/?activity=AFarewellToArms-RevCap-C2-EN.clipflair
agComhaireamhCountingRND.clipflair --- http://studio.clipflair.net/?activity=agComhaireamhCountingRND.clipflair
----------
Al-imtihan-CapRev-B1-AR.clipflair --- http://studio.clipflair.net/?activity=Al-imtihan-CapRev-B1-AR.clipflair
AlBar-Cap-B1-B2-IT.clipflair --- http://studio.clipflair.net/?activity=AlBar-Cap-B1-B2-IT.clipflair
...
I'm quite new to XSLT.
This is the problem I'm trying to solve for hours now:
I auto-generate a table of contents for a xml document which works great so far. However I'd like to replace a placeholder tag in my source xml with that just generated toc code.
So the output should include the whole document with replaced placeholder-toc-tag with the auto-generated toc xml.
This is what I've tried:
Let's say I have my placeholderTag anywhere in the document and want to replace this/those. I thought that I could loop through all nodes by node() and check if the node name equals my placeholder tag:
<xsl:template match="node()">
<xsl:choose>
<xsl:when test="divGen">
<!-- apply other template to generate toc-->
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="node()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
However the if statement won't match like this.
edit:
Ok, here's the source document (TEI coded - TEI namespace removed):
<TEI>
<teiHeader>
<fileDesc>
<titleStmt>
<title>Title</title>
</titleStmt>
<publicationStmt>
<p>Publication information</p>
</publicationStmt>
<sourceDesc>
<p>Information about the source</p>
</sourceDesc>
</fileDesc>
</teiHeader>
<text>
<front>
<titlePage>
<byline>title page details</byline>
</titlePage>
</front>
<body>
<divGen type="toc"/>
<div type="part">
<div type="section">
<head>heading1</head>
</div>
<div type="section">
<head>heading2</head>
</div>
</div>
<div type="part">
<div type="section">
<head>heading3</head>
</div>
<div type="section">
<head>heading4</head>
</div>
<div type="section">
<head>heading5</head>
</div>
</div>
</body>
<back> </back>
</text>
I'd like to auto-generate the toc from the head values and replace the divGen tag by the auto-produced toc code. However please notice that the divGen tag can be anywhere in the document but not outside of body.
Any ideas?
Chris
Good question, +1.
Here is a complete transformation (with mock TOC generation to be replaced by real one) that shows how to do this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vTOC">
<xsl:apply-templates mode="TOC"/>
<mockTOC>
<xsl:comment>The real TOC generated here</xsl:comment>
</mockTOC>
</xsl:variable>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="divGen[#type='toc']">
<xsl:copy-of select="$vTOC"/>
</xsl:template>
<xsl:template match="text()" mode="TOC"/>
</xsl:stylesheet>
when this transformation is applied on the provided XML document:
<TEI>
<teiHeader>
<fileDesc>
<titleStmt>
<title>Title</title>
</titleStmt>
<publicationStmt>
<p>Publication information</p>
</publicationStmt>
<sourceDesc>
<p>Information about the source</p>
</sourceDesc>
</fileDesc>
</teiHeader>
<text>
<front>
<titlePage>
<byline>title page details</byline>
</titlePage>
</front>
<body>
<divGen type="toc"/>
<div type="part">
<div type="section">
<head>heading1</head>
</div>
<div type="section">
<head>heading2</head>
</div>
</div>
<div type="part">
<div type="section">
<head>heading3</head>
</div>
<div type="section">
<head>heading4</head>
</div>
<div type="section">
<head>heading5</head>
</div>
</div>
</body>
<back>
</back>
</text>
</TEI>
the correct, wanted output is produced, in which any occurences of <divGen type="toc"/> are replaced by the generated TOC:
<TEI>
<teiHeader>
<fileDesc>
<titleStmt>
<title>Title</title>
</titleStmt>
<publicationStmt>
<p>Publication information</p>
</publicationStmt>
<sourceDesc>
<p>Information about the source</p>
</sourceDesc>
</fileDesc>
</teiHeader>
<text>
<front>
<titlePage>
<byline>title page details</byline>
</titlePage>
</front>
<body>
<mockTOC><!--The real TOC generated here--></mockTOC>
<div type="part">
<div type="section">
<head>heading1</head>
</div>
<div type="section">
<head>heading2</head>
</div>
</div>
<div type="part">
<div type="section">
<head>heading3</head>
</div>
<div type="section">
<head>heading4</head>
</div>
<div type="section">
<head>heading5</head>
</div>
</div>
</body>
<back/>
</text>
</TEI>
Explanation: Use of modes to pre-generate the TOC in a variable, then overriding the identity rule for any TOC placeholder.
Im guessing somewhere u have a template like
<xsl:template match="/">
<xsl:apply-templates select="*"/>
</xsl:template>
then u want the template to only match your placeholderTag
then the others will default to your other nodes!
<xsl:template match="placeholderTag">
<!-- applying generate toc thing-->
</xsl:template>
<xsl:template match="node()">
<xsl:copy-of select="node()"/>
</xsl:template>
I have a HTML page (fully valid) that is post-processed by XSLT.
Let's say the relevant section of code looks like this:
<div id="content"> ... </div>
...
<div id="announcement"> ... </div>
The XSLT needs to transform it to look like this:
<div id="content"> <div id="announcement"> ... </div> ... </div>
Any ideas? I'm stuck.
Edit: Indicated that <div id="content"> and <div id="announcement"> are separated by other code.
If the announcement div directly follows the content div, use:
<xsl:template match="div[#id='content' and following-sibling::div[1][#id='announcement']">
<!-- copy the content div and its attributes -->
<xsl:copy>
<xsl:copy-of select="#*" />
<!-- now make a copy of the directly following announcement div -->
<xsl:copy-of select="following-sibling::div[1][#id='announcement']" />
<!-- process the rest of the contents -->
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<!-- the empty template mutes an announcement div that follows a content div -->
<xsl:template match="div[#id='announcement' and preceding-sibling::div[1][#id='content']" />
The above is specific enough not to touch any other divs that might be in your document. If your situation allows, you can make it simpler/less specific to increase readability.