On Sun, Nov 22 2009 03:24:40 +0000, ms419(_at_)freezone(_dot_)co(_dot_)uk wrote:
...
I think the problem is that the stylesheet uses the document() function
to get HTML pages from the web,
<xsl:template match="html:a" mode="foo">
<fo:block>
<xsl:apply-templates select="document(@href)//html:body"/>
</fo:block>
</xsl:template>
- and these pages, e.g. http://ica-atom.org/docs/index.php?title=UM-2.1
- have some relative images,
e.g. /docs/images/thumb/b/bb/UM-2.1.png/500px-UM-2.1.png
The <img> elements are part of the HTML document, and so relative to
http://ica-atom.org/docs/index.php?title=UM-2.1, but I guess the
<external-graphic> elements aren't?
I tried adding an xml:base="" attribute,
<xsl:template match="html:a" mode="foo">
<fo:block xml:base="{(_at_)href}">
<xsl:apply-templates select="document(@href)//html:body"/>
</fo:block>
</xsl:template>
FWIW, support for xml:base is in the XSL 2.0 Requirements
(http://www.w3.org/TR/xslfo20-req/#N67190). Feedback on the
requirements and on the current Working Draft are always welcome.
...
How can I automatically convert these HTML pages to a PDF with XSL-FO?
As Florent noted, resolve-uri() is only in XPath 2.0. You could do the
transformation to FO outside FOP using a XSLT 2.0 processor, or you
could merge the two URLs using XSLT 1.0.
I had the impression that this sort of problem had been covered before,
but I couldn't find a XSLT 1.0 solution in the list archives. The
'merge-dirnames' template below is based on templates in the xmlroff
testing module (http://xmlroff.org/browser/trunk/testing/common.xsl),
though I had to add new code to handle your combination of 'http:' URL
plus absolute filename (and I haven't tested it, sorry). There's also a
'dirname' template so you can get the dirname of first HTML page (not
that it's strictly necessary for the case that you've shown).
Regards,
Tony Graham
Tony(_dot_)Graham(_at_)MenteithConsulting(_dot_)com
Director W3C XSL FO SG Invited Expert
Menteith Consulting Ltd XML Guild member
XML, XSL and XSLT consulting, programming and training
Registered Office: 13 Kelly's Bay Beach, Skerries, Co. Dublin, Ireland
Registered in Ireland - No. 428599 http://www.menteithconsulting.com
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
xmlroff XSL Formatter http://xmlroff.org
xslide Emacs mode http://www.menteith.com/wiki/xslide
Unicode: A Primer urn:isbn:0-7645-4625-2
<xsl:variable name="DEBUG"/>
<!-- merge-dirnames
- $dirname1: Potential base for a relative directory name
- $dirname2: directory name to merge
- $separator: String to use when concatenating directories. Optional.
-
- Merge $dirname1 and $dirname2 such that if $dirname2 is
- a relative path, the result is relative to $dirname1.
-
- Also handles if either name or both names are empty.
-->
<xsl:template name="merge-dirnames">
<xsl:param name="dirname1"/>
<xsl:param name="dirname2"/>
<xsl:param name="separator" select="'/'"/>
<xsl:if test="$DEBUG >= 2">
<xsl:message>
<xsl:text>merge-dirname:: dirname1: '</xsl:text>
<xsl:value-of select="$dirname1"/>
<xsl:text>'; dirname2: '</xsl:text>
<xsl:value-of select="$dirname2"/>
<xsl:text>'</xsl:text>
</xsl:message>
</xsl:if>
<xsl:variable name="merged-dirname">
<xsl:choose>
<xsl:when test="substring($dirname2, 1, 5) = 'http:'">
<xsl:value-of select="$dirname2"/>
</xsl:when>
<xsl:when test="$dirname1 != ''">
<xsl:choose>
<xsl:when test="$dirname2 != ''">
<xsl:choose>
<xsl:when test="substring($dirname2, 1, 1) = $separator">
<xsl:if test="substring($dirname1, 1, 7) = 'http://'">
<xsl:value-of select="concat('http://',
substring-before(substring($dirname1, 8), '/'))"/>
</xsl:if>
<xsl:value-of select="$dirname2"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($dirname1, $separator,
$dirname2)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$dirname1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$dirname2">
<xsl:value-of select="$dirname2"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>.</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$DEBUG >= 2">
<xsl:message>
<xsl:text>merge-dirname:: merged dirname: '</xsl:text>
<xsl:value-of select="$merged-dirname"/>
<xsl:text>'</xsl:text>
</xsl:message>
<xsl:message><xsl:text> </xsl:text></xsl:message>
</xsl:if>
<xsl:value-of select="$merged-dirname"/>
</xsl:template>
<!-- dirname
- $string: Pathname for which to get the directory name
- $separator: String separating directory names. Default is '/'.
-
- Gets the directory name (the part before the last $separator)
- of $string.
-->
<xsl:template name="dirname">
<xsl:param name="string"/>
<xsl:param name="separator" select="'/'"/>
<xsl:variable name="the-rest" select="substring-after($string,
$separator)"/>
<xsl:if test="$DEBUG >= 2">
<xsl:message>
<xsl:text>dirname:: $string: '</xsl:text>
<xsl:value-of select="$string"/>
<xsl:text>'; $the-rest: '</xsl:text>
<xsl:value-of select="$the-rest"/>
<xsl:text>' </xsl:text>
</xsl:message>
</xsl:if>
<xsl:value-of select="substring-before($string, $separator)"/>
<xsl:if test="contains($the-rest, '/')">
<xsl:text>/</xsl:text>
<xsl:call-template name="dirname">
<xsl:with-param name="string" select="$the-rest"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--