URIResolver's resolve() method is not invoked when document() function is used
in stylesheet. For xsl:import and xsl:include URIResolver's resolve method is
invoked as expected. But for document() method it doesn't work.
For the following stylesheet named "doctest.xsl"
-------------------------------------------------------------------------------
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" version="4.0" indent="yes" encoding="iso-8859-1"/>
<xsl:template match="/">
<html>
<body>
<xsl:variable name="colors" select="document('colors.xml')/colors"/>
<p>Nodes in color <xsl:value-of select="count($colors)"/></p>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
-------------------------------------------------------------------------------
colors.xml file:
-------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<colors>
<dark>
<container name="book">
<category name="developer" version="1">088ea6</category>
<category name="default" version="1">0839a6</category>
</container>
</dark>
</colors>
-------------------------------------------------------------------------------
On command line if we give,
java org.apache.xalan.xslt.Process -XSL doctest.xsl -URIRESOLVER TestURIR
it would print out,
href <colors.xml> base <file:/home/kmeduri/rnd/doctest.xsl>
href <colors.xml> base <file:/home/kmeduri/rnd/doctest.xsl>
<html>
<body>
<p>Nodes in color 1</p>
</body>
</html>
invoking resolve method of TestURIR.java.
TestURIR.java
--------------------------------------------------------------------------------
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
public class TestURIR implements URIResolver {
public static void main(String[] str) {
/*At SYSTEM_ID, both doctest.xsl and colors.xml (which is sent as
*argument to document() function ) exist */
String SYSTEM_ID="file:///home/kmeduri/rnd/";
TransformerFactory tfactory = TransformerFactory.newInstance();
tfactory.setURIResolver(new TestURIR());
try {
StreamSource streamSource = new StreamSource(new
FileInputStream("doctest.xsl"));
streamSource.setSystemId(SYSTEM_ID);
Transformer transformer = tfactory.newTransformer(streamSource);
} catch (Exception e) {
System.out.println("Exception raised <" + e.getMessage() + ">");
}
} // end of main()
public Source resolve(String href, String base) {
System.out.println("href <" + href + "> base <" + base + ">");
return null;
}
} // end of class
--------------------------------------------------------------------------------
If we run this program using
java TestURIR
it doesn't invoke resolve method which it should.
The documentation for URIResolver says,
"Called by the processor when it encounters an xsl:include, xsl:import,
or document() function."
For the same java program, if citiesinclude.xsl file is used (instead of
doctest.xsl) which uses xsl:include to include cities.xsl file, the "resolve" method is invoked and the following is printed.
href <cities.xsl> base <file:///home/kmeduri/rnd/>
where the files are as follows:
citiesinclude.xsl
=================
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:include href="cities.xsl"/>
</xsl:stylesheet>
cities.xsl
==========
<?xml version="1.0" standalone="yes"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="unique-countries"
select="/cities
/city[not(@country=preceding-sibling::city/@country)]
/@country"
/>
<countries>
<xsl:for-each select="$unique-countries">
<country name="{.}">
<xsl:for-each select="//city[@country=current()]">
<city><xsl:value-of select="@name"/></city>
</xsl:for-each>
</country>
</xsl:for-each>
</countries>
</xsl:template>
</xsl:stylesheet>
|