I made a xsl merge two xml to one, then using the output to another xsl for a html view.
When I use xmlSpy to test it, it works very well, but when I put them under a java web application, somethings is wrong.
The xsl is as follows:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8" />
<xsl:strip-space elements="*" />
<xsl:variable name="xsdresult" select="document('xsdResult.xml')" />
<xsl:variable name="schresult" select="document('result.xml')" />
<xsl:template match="/">
<xsl:result-document href="fullresult.xml" method="xml">
<fullresult>
<xsl:copy-of select="$schresult/node()" />
<xsl:copy-of select="$xsdresult/node()" />
</fullresult>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
And this file and xml files are all under the same directory and the output file is the same.
A jsp to apply this xslt:
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@taglib uri="http://jakarta.apache.org/taglibs/xsl-1.0" prefix="xsl"%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<%@ page%>
<title>test</title>
</head>
<body>
<p>
<xsl:apply xml="WEB-INF/classes/result/result.xml" xsl="WEB-INF/classes/result/merge.xsl" />
<xsl:apply xml="WEB-INF/classes/result/xsdResult.xml" xsl="WEB-INF/classes/result/merge.xsl" />
<xsl:apply xml="WEB-INF/classes/result/fullresult.xml" xsl="WEB-INF/classes/result/anotherone.xsl" />
</p>
</body>
</html>
The problem is in the merge.xsl, document(‘xsdResult.xml’) and document(‘result.xml’), they are always searching under eclipse_home directory, not the tomcat webapps direcotry.
What you need is the URI Resolver. Looking at what happens inside the ApplyTag I don’t see how you would be able to provide your own.
There seems to be another Apache taglib for doing similar things – xtags. The
StyleTagin there seems to do a better job compared to theApplyTag, it is using an URI Resolver (look at line 154). However, I don’t see a clean way to pass your own without subclassing from it. You may trace the code further into the URLHelper and see if modifying the URI within thedocument()function to be something like/WEB-INF/...will yield better results.That said, however, you will very likely run into another issue with the second step of your transformation where you expect to pick up the result of the first pass from the file system. Where to will the first pass dump the
fullresult.xml? does the process the application server runs on behalf of have permissions to write to the file system in there? Do you even want it to write to the file system?I feel like you would be much better off putting together a small utility class in plain Java that would pipe your transformations using JAXP API. You would have all the control you want over parser features including the URI resolution and you wouldn’t need to use filesystem as an intermediate store. And when you do that, you can also consider running your transformation in a single pass. You can merge your documents into a
xsl:variableand then apply templates on it or just apply templates to the result of eachdocument()function individually. Unless, of course, you need to retain the result of the XML merge as well.Hope it helps