Re: [docbook-apps] Embedding DocBook → PD F transformation in a Java web app

Paul Hoadley <[email protected]> Sat, 29 Jul 2023 18:04:04 +0930
Newsgroups gmane.text.docbook.apps
Message-ID <[email protected]>
--Apple-Mail=_391EE2D9-1084-4EE6-878B-7EC8996C1C95
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=us-ascii

On 29 Jul 2023, at 13:48, Paul Hoadley <[email protected]> wrote:

> I'll put together a minimal example and see if you can put me in the =
right direction.

To recap, I'm building a Java project that will encapsulate the DocBook =
stylesheets and some classes to do some transformations, all packaged as =
a JAR to become part of a larger web app. The project uses the standard =
Maven layout, and Saxon-HE 12.3. I've put the XSL in =
src/main/resources/xsl:

paulh@elmo xsl % pwd
/Users/paulh/Projects/Java/janus/src/main/resources/xsl
paulh@elmo xsl % ls -l
total 688
drwxr-xr-x@ 48 paulh  staff    1536 29 Jul  2020 docbook-xsl-1.79.2
-rw-r--r--   1 paulh  staff   16681 24 Jul 10:41 header-footer.xsl
-rw-r--r--   1 paulh  staff    7494 28 Jul 14:23 juno-driver.xsl
-rw-r--r--   1 paulh  staff    8689 24 Jul 14:33 table.xsl
-rw-r--r--   1 paulh  staff  307717 18 Jul 12:49 titlepage.xsl

juno-driver.xsl is the top-level customisation stylesheet, and it =
imports the others:

  <xsl:import href=3D"docbook-xsl-1.79.2/fo/docbook.xsl" />
  <xsl:import href=3D"titlepage.xsl" />
  <xsl:import href=3D"table.xsl" />
  <xsl:import href=3D"header-footer.xsl" />

To be clear, addressing the XSL stylesheets as files on the filesystem =
works just fine. That is, this does exactly what it should:

private Document transformDocument(Document document) throws =
TransformerException, FileNotFoundException {
	DOMResult result =3D new DOMResult();
	TransformerFactory factory =3D TransformerFactory.newInstance();
	factory.setURIResolver(new StandardURIResolver());
	InputStream is =3D new FileInputStream(new =
File("/Users/paulh/Projects/Java/janus/src/main/resources/xsl/juno-driver.=
xsl"));
	Source source =3D new StreamSource(is, =
"file:/Users/paulh/Projects/Java/janus/src/main/resources/xsl/juno-driver.=
xsl");
	Transformer transformer =3D factory.newTransformer(source);
	transformer.transform(new DOMSource(document), result);
	return (Document) result.getNode();
}

What I want to do, though, is reference the stylesheets as classpath =
resources. StandardURIResolver claims to be able to handle the =
"classpath URI scheme", so I tried this:

private Document transformDocument(Document document) throws =
TransformerException, FileNotFoundException {
	DOMResult result =3D new DOMResult();
	TransformerFactory factory =3D TransformerFactory.newInstance();
	factory.setURIResolver(new StandardURIResolver());
	InputStream is =3D =
XmlTest.class.getResourceAsStream("/xsl/juno-driver.xsl");
	Source source =3D new StreamSource(is, =
"classpath:/xsl/juno-driver.xsl");
	Transformer transformer =3D factory.newTransformer(source);
	transformer.transform(new DOMSource(document), result);
	return (Document) result.getNode();
}

Which results in:

Error=20
  XTSE0165: I/O error reported by XML parser processing
  classpath:xsl/docbook-xsl-1.79.2/fo/docbook.xsl: unknown protocol: =
classpath
javax.xml.transform.TransformerConfigurationException: =
net.sf.saxon.s9api.SaxonApiException: I/O error reported by XML parser =
processing classpath:xsl/docbook-xsl-1.79.2/fo/docbook.xsl
	at =
net.sf.saxon.jaxp.SaxonTransformerFactory.newTemplates(SaxonTransformerFac=
tory.java:158)
	at =
net.sf.saxon.jaxp.SaxonTransformerFactory.newTransformer(SaxonTransformerF=
actory.java:112)
	at =
net.logicsquad.janus.XmlTest.transformDocument(XmlTest.java:142)

If StandardURIResolver can handle classpath URIs, have I just got the =
syntax or other usage wrong somewhere?


--=20
Paul Hoadley
https://logicsquad.net/
https://www.linkedin.com/company/logic-squad/


--Apple-Mail=_391EE2D9-1084-4EE6-878B-7EC8996C1C95
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=us-ascii

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; =
charset=3Dus-ascii"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; line-break: after-white-space;" class=3D"">On =
29 Jul 2023, at 13:48, Paul Hoadley &lt;<a =
href=3D"mailto:[email protected]" =
class=3D"">[email protected]</a>&gt; wrote:<div class=3D""><br =
class=3D""></div><div class=3D""><div><blockquote type=3D"cite" =
class=3D""><div class=3D""><div class=3D"" style=3D"caret-color: rgb(0, =
0, 0); font-family: LucidaGrande; font-size: 14px; font-style: normal; =
font-variant-caps: normal; font-weight: 400; letter-spacing: normal; =
text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; =
text-decoration: none;"><div class=3D""><div class=3D"">I'll put =
together a minimal example and see if you can put me in the right =
direction.</div></div></div></div></blockquote><div><br =
class=3D""></div><div>To recap, I'm building a Java project that will =
encapsulate the DocBook stylesheets and some classes to do some =
transformations, all packaged as a JAR to become part of a larger web =
app. The project uses the standard Maven layout, and Saxon-HE 12.3. I've =
put the XSL in src/main/resources/xsl:</div><div><br =
class=3D""></div><div><div style=3D"margin: 0px; font-stretch: normal; =
font-size: 13px; line-height: normal; font-family: Menlo;" =
class=3D""><span style=3D"font-variant-ligatures: no-common-ligatures" =
class=3D"">paulh@elmo xsl % pwd</span></div><div style=3D"margin: 0px; =
font-stretch: normal; font-size: 13px; line-height: normal; font-family: =
Menlo;" class=3D""><span style=3D"font-variant-ligatures: =
no-common-ligatures" =
class=3D"">/Users/paulh/Projects/Java/janus/src/main/resources/xsl</span><=
/div><div style=3D"margin: 0px; font-stretch: normal; font-size: 13px; =
line-height: normal; font-family: Menlo;" class=3D""><span =
style=3D"font-variant-ligatures: no-common-ligatures" =
class=3D"">paulh@elmo xsl % ls -l</span></div><div style=3D"margin: 0px; =
font-stretch: normal; font-size: 13px; line-height: normal; font-family: =
Menlo;" class=3D""><span style=3D"font-variant-ligatures: =
no-common-ligatures" class=3D"">total 688</span></div><div =
style=3D"margin: 0px; font-stretch: normal; font-size: 13px; =
line-height: normal; font-family: Menlo;" class=3D""><span =
style=3D"font-variant-ligatures: no-common-ligatures" =
class=3D"">drwxr-xr-x@ 48 paulh&nbsp; staff&nbsp; &nbsp; 1536 29 =
Jul&nbsp; 2020 docbook-xsl-1.79.2</span></div><div style=3D"margin: 0px; =
font-stretch: normal; font-size: 13px; line-height: normal; font-family: =
Menlo;" class=3D""><span style=3D"font-variant-ligatures: =
no-common-ligatures" class=3D"">-rw-r--r-- &nbsp; 1 paulh&nbsp; staff =
&nbsp; 16681 24 Jul 10:41 header-footer.xsl</span></div><div =
style=3D"margin: 0px; font-stretch: normal; font-size: 13px; =
line-height: normal; font-family: Menlo;" class=3D""><span =
style=3D"font-variant-ligatures: no-common-ligatures" =
class=3D"">-rw-r--r-- &nbsp; 1 paulh&nbsp; staff&nbsp; &nbsp; 7494 28 =
Jul 14:23 juno-driver.xsl</span></div><div style=3D"margin: 0px; =
font-stretch: normal; font-size: 13px; line-height: normal; font-family: =
Menlo;" class=3D""><span style=3D"font-variant-ligatures: =
no-common-ligatures" class=3D"">-rw-r--r-- &nbsp; 1 paulh&nbsp; =
staff&nbsp; &nbsp; 8689 24 Jul 14:33 table.xsl</span></div><div =
style=3D"margin: 0px; font-stretch: normal; font-size: 13px; =
line-height: normal; font-family: Menlo;" class=3D""><span =
style=3D"font-variant-ligatures: no-common-ligatures" =
class=3D"">-rw-r--r-- &nbsp; 1 paulh&nbsp; staff&nbsp; 307717 18 Jul =
12:49 titlepage.xsl</span></div><div class=3D""><span =
style=3D"font-variant-ligatures: no-common-ligatures" class=3D""><br =
class=3D""></span></div></div></div><div class=3D"">juno-driver.xsl is =
the top-level customisation stylesheet, and it imports the =
others:</div><div class=3D""><br class=3D""></div><div class=3D""><div =
style=3D"margin: 0px; font-stretch: normal; font-size: 12px; =
line-height: normal; font-family: Menlo; color: rgb(42, 161, 152);" =
class=3D""><span style=3D"color: #000000" =
class=3D"">&nbsp;&nbsp;&lt;</span><span style=3D"color: #268bd2" =
class=3D"">xsl:import</span><span style=3D"color: #000000" class=3D""> =
</span><span style=3D"color: #93a1a1" class=3D"">href</span><span =
style=3D"color: #000000" class=3D"">=3D</span><span style=3D"color: =
#93a1a1" class=3D"">"</span>docbook-xsl-1.79.2/fo/docbook.xsl<span =
style=3D"color: #93a1a1" class=3D"">"</span><span style=3D"color: =
#000000" class=3D""> /&gt;</span></div><div style=3D"margin: 0px; =
font-stretch: normal; font-size: 12px; line-height: normal; font-family: =
Menlo; color: rgb(42, 161, 152);" class=3D""><span style=3D"color: =
#000000" class=3D"">&nbsp; &lt;</span><span style=3D"color: #268bd2" =
class=3D"">xsl:import</span><span style=3D"color: #000000" class=3D""> =
</span><span style=3D"color: #93a1a1" class=3D"">href</span><span =
style=3D"color: #000000" class=3D"">=3D</span><span style=3D"color: =
#93a1a1" class=3D"">"</span>titlepage.xsl<span style=3D"color: #93a1a1" =
class=3D"">"</span><span style=3D"color: #000000" class=3D""> =
/&gt;</span></div><div style=3D"margin: 0px; font-stretch: normal; =
font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(38, =
139, 210);" class=3D""><span style=3D"color: #000000" class=3D"">&nbsp; =
&lt;</span>xsl:import<span style=3D"color: #000000" class=3D""> =
</span><span style=3D"color: #93a1a1" class=3D"">href</span><span =
style=3D"color: #000000" class=3D"">=3D</span><span style=3D"color: =
#93a1a1" class=3D"">"</span><span style=3D"color: #2aa198" =
class=3D"">table.xsl</span><span style=3D"color: #93a1a1" =
class=3D"">"</span><span style=3D"color: #000000" class=3D""> =
/&gt;</span></div><div style=3D"margin: 0px; font-stretch: normal; =
font-size: 12px; line-height: normal; font-family: Menlo; color: rgb(42, =
161, 152);" class=3D""><span style=3D"color: #000000" class=3D"">&nbsp; =
&lt;</span><span style=3D"color: #268bd2" =
class=3D"">xsl:import</span><span style=3D"color: #000000" class=3D""> =
</span><span style=3D"color: #93a1a1" class=3D"">href</span><span =
style=3D"color: #000000" class=3D"">=3D</span><span style=3D"color: =
#93a1a1" class=3D"">"</span>header-footer.xsl<span style=3D"color: =
#93a1a1" class=3D"">"</span><span style=3D"color: #000000" class=3D""> =
/&gt;</span></div></div><div class=3D""><br class=3D""></div><div =
class=3D"">To be clear, addressing the XSL stylesheets as files on the =
filesystem works just fine. That is, this does exactly what it =
should:</div><div class=3D""><br class=3D""></div><div class=3D""><div =
class=3D""><font face=3D"Menlo" size=3D"2" class=3D""><span =
style=3D"font-style: normal;" class=3D"">private Document =
transformDocument(Document document) throws TransformerException, =
FileNotFoundException {</span></font></div><div class=3D""><font =
face=3D"Menlo" size=3D"2" class=3D""><span style=3D"font-style: normal;" =
class=3D""><span class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>DOMResult result =3D new DOMResult();</span></font></div><div =
class=3D""><font face=3D"Menlo" size=3D"2" class=3D""><span =
style=3D"font-style: normal;" class=3D""><span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>TransformerFactory factory =3D =
TransformerFactory.newInstance();</span></font></div><div class=3D""><font=
 face=3D"Menlo" size=3D"2" class=3D""><span style=3D"font-style: =
normal;" class=3D""><span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>factory.setURIResolver(new =
StandardURIResolver());</span></font></div><div class=3D""><font =
face=3D"Menlo" size=3D"2" class=3D""><span style=3D"font-style: normal;" =
class=3D""><span class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>InputStream is =3D new FileInputStream(new =
File("/Users/paulh/Projects/Java/janus/src/main/resources/xsl/juno-driver.=
xsl"));</span></font></div><div class=3D""><font face=3D"Menlo" size=3D"2"=
 class=3D""><span style=3D"font-style: normal;" class=3D""><span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>Source =
source =3D new StreamSource(is, =
"file:/Users/paulh/Projects/Java/janus/src/main/resources/xsl/juno-driver.=
xsl");</span></font></div><div class=3D""><font face=3D"Menlo" size=3D"2" =
class=3D""><span style=3D"font-style: normal;" class=3D""><span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>Transformer transformer =3D =
factory.newTransformer(source);</span></font></div><div class=3D""><font =
face=3D"Menlo" size=3D"2" class=3D""><span style=3D"font-style: normal;" =
class=3D""><span class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>transformer.transform(new DOMSource(document), =
result);</span></font></div><div class=3D""><font face=3D"Menlo" =
size=3D"2" class=3D""><span style=3D"font-style: normal;" class=3D""><span=
 class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>return =
(Document) result.getNode();</span></font></div><div class=3D""><font =
face=3D"Menlo" size=3D"2" class=3D""><span style=3D"font-style: normal;" =
class=3D"">}</span></font></div></div><div class=3D""><br =
class=3D""></div><div class=3D"">What I want to do, though, is reference =
the stylesheets as classpath resources.&nbsp;StandardURIResolver claims =
to be able to handle the "classpath URI scheme", so I tried =
this:</div><div class=3D""><br class=3D""></div><div class=3D""><div =
class=3D""><span style=3D"font-style: normal;" class=3D""><font =
face=3D"Menlo" size=3D"2" class=3D"">private Document =
transformDocument(Document document) throws TransformerException, =
FileNotFoundException {</font></span></div><div class=3D""><span =
style=3D"font-style: normal;" class=3D""><font face=3D"Menlo" size=3D"2" =
class=3D""><span class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>DOMResult result =3D new DOMResult();</font></span></div><div =
class=3D""><span style=3D"font-style: normal;" class=3D""><font =
face=3D"Menlo" size=3D"2" class=3D""><span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>TransformerFactory factory =3D =
TransformerFactory.newInstance();</font></span></div><div class=3D""><span=
 style=3D"font-style: normal;" class=3D""><font face=3D"Menlo" size=3D"2" =
class=3D""><span class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>factory.setURIResolver(new =
StandardURIResolver());</font></span></div><div class=3D""><span =
style=3D"font-style: normal;" class=3D""><font face=3D"Menlo" size=3D"2" =
class=3D""><span class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>InputStream is =3D =
XmlTest.class.getResourceAsStream("/xsl/juno-driver.xsl");</font></span></=
div><div class=3D""><span style=3D"font-style: normal;" class=3D""><font =
face=3D"Menlo" size=3D"2" class=3D""><span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>Source source =3D new =
StreamSource(is, =
"classpath:/xsl/juno-driver.xsl");</font></span></div><div =
class=3D""><span style=3D"font-style: normal;" class=3D""><font =
face=3D"Menlo" size=3D"2" class=3D""><span class=3D"Apple-tab-span" =
style=3D"white-space:pre">	</span>Transformer transformer =3D =
factory.newTransformer(source);</font></span></div><div class=3D""><span =
style=3D"font-style: normal;" class=3D""><font face=3D"Menlo" size=3D"2" =
class=3D""><span class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>transformer.transform(new DOMSource(document), =
result);</font></span></div><div class=3D""><span style=3D"font-style: =
normal;" class=3D""><font face=3D"Menlo" size=3D"2" class=3D""><span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>return =
(Document) result.getNode();</font></span></div><div class=3D""><span =
style=3D"font-style: normal;" class=3D""><font face=3D"Menlo" size=3D"2" =
class=3D"">}</font></span></div></div><div class=3D""><br =
class=3D""></div><div class=3D"">Which results in:</div><div =
class=3D""><br class=3D""></div><div class=3D""><div style=3D"margin: =
0px; font-stretch: normal; font-size: 12px; line-height: normal; =
font-family: Menlo; color: rgb(255, 0, 0);" =
class=3D"">Error&nbsp;</div><div style=3D"margin: 0px; font-stretch: =
normal; font-size: 12px; line-height: normal; font-family: Menlo; color: =
rgb(255, 0, 0);" class=3D"">&nbsp; XTSE0165: I/O error reported by XML =
parser processing</div><div style=3D"margin: 0px; font-stretch: normal; =
font-size: 12px; line-height: normal; font-family: Menlo; color: =
rgb(255, 0, 0);" class=3D"">&nbsp; =
classpath:xsl/docbook-xsl-1.79.2/fo/docbook.xsl: unknown protocol: =
classpath</div><div style=3D"margin: 0px; font-stretch: normal; =
font-size: 12px; line-height: normal; font-family: Menlo; color: =
rgb(255, 0, 0);" class=3D""><span style=3D"text-decoration: underline ; =
color: #0068da" =
class=3D"">javax.xml.transform.TransformerConfigurationException</span>: =
<span style=3D"text-decoration: underline ; color: #0068da" =
class=3D"">net.sf.saxon.s9api.SaxonApiException</span>: I/O error =
reported by XML parser processing =
classpath:xsl/docbook-xsl-1.79.2/fo/docbook.xsl</div><div style=3D"margin:=
 0px; font-stretch: normal; font-size: 12px; line-height: normal; =
font-family: Menlo; color: rgb(255, 0, 0);" class=3D""><span =
class=3D"Apple-tab-span" style=3D"white-space:pre">	</span>at =
net.sf.saxon.jaxp.SaxonTransformerFactory.newTemplates(<span =
style=3D"text-decoration: underline ; color: #0068da" =
class=3D"">SaxonTransformerFactory.java:158</span>)</div><div =
style=3D"margin: 0px; font-stretch: normal; font-size: 12px; =
line-height: normal; font-family: Menlo; color: rgb(255, 0, 0);" =
class=3D""><span class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>at net.sf.saxon.jaxp.SaxonTransformerFactory.newTransformer(<span =
style=3D"text-decoration: underline ; color: #0068da" =
class=3D"">SaxonTransformerFactory.java:112</span>)</div><div =
style=3D"margin: 0px; font-stretch: normal; font-size: 12px; =
line-height: normal; font-family: Menlo; color: rgb(255, 0, 0);" =
class=3D""><span class=3D"Apple-tab-span" style=3D"white-space:pre">	=
</span>at net.logicsquad.janus.XmlTest.transformDocument(<span =
style=3D"text-decoration: underline ; color: #0068da" =
class=3D"">XmlTest.java:142</span>)</div></div><div class=3D""><br =
class=3D""></div><div class=3D"">If StandardURIResolver can handle =
classpath URIs, have I just got the syntax or other usage wrong =
somewhere?</div><div class=3D""><br class=3D""></div><br class=3D""><div =
class=3D"">
<div style=3D"color: rgb(0, 0, 0); letter-spacing: normal; text-align: =
start; text-indent: 0px; text-transform: none; white-space: normal; =
word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: =
break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" =
class=3D""><div style=3D"color: rgb(0, 0, 0); letter-spacing: normal; =
text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: =
break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" =
class=3D""><span class=3D"Apple-style-span" style=3D"border-collapse: =
separate; font-variant-ligatures: normal; font-variant-position: normal; =
font-variant-numeric: normal; font-variant-alternates: normal; =
font-variant-east-asian: normal; font-weight: normal; line-height: =
normal; border-spacing: 0px; -webkit-text-decorations-in-effect: =
none;"><div style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; =
line-break: after-white-space;" class=3D"">--&nbsp;<br class=3D"">Paul =
Hoadley<br class=3D""><a href=3D"https://logicsquad.net/" =
class=3D"">https://logicsquad.net/</a><br =
class=3D"">https://www.linkedin.com/company/logic-squad/</div><div =
style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; line-break: =
after-white-space;" class=3D""><br =
class=3D""></div></span></div></div></div></div></body></html>=

--Apple-Mail=_391EE2D9-1084-4EE6-878B-7EC8996C1C95--