Reputation: 1749
I'm getting mad about a simple XSL transformation. After a lot of test I've seen that it depends on Xalan (because with Saxon it works). I've forced Java to use Xalan processor so I'm sure.
The only rule that is matched is the "identity rule" while the others "match" are not done. If I use saxon all works fine!
Can you see something wrong in this XSL transf?
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="xhtml xsl">
<xsl:output method="xml" omit-xml-declaration="no"
media-type="text/xml" indent="yes" encoding="UTF-8"
doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" />
<xsl:template match="/">
<xsl:message>root</xsl:message>
<xsl:apply-templates select="xhtml:html" />
</xsl:template>
<xsl:template match="xhtml:html">
<xsl:element name="html">
<xsl:attribute name="xml:lang">it</xsl:attribute>
<xsl:apply-templates select="xhtml:head|xhtml:body" />
</xsl:element>
<xsl:message>xhtml:html</xsl:message>
</xsl:template>
<xsl:template match="xhtml:head">
<xsl:element name="head">
<xsl:apply-templates select="xhtml:meta" />
<title>
<xsl:value-of select="xhtml:title" />
</title>
<link href="%stile.css%" rel="stylesheet" type="text/css" />
<xsl:apply-templates select="xhtml:script" />
</xsl:element>
<xsl:message>xhtml:head</xsl:message>
</xsl:template>
<xsl:template match="xhtml:body">
<xsl:element name="body">
<xsl:apply-templates select="descendant::xhtml:div[@class='sxSmall']" />
</xsl:element>
<xsl:message>xhtml:body</xsl:message>
</xsl:template>
<xsl:template match="xhtml:script">
<xsl:message>xhtml:script</xsl:message>
</xsl:template>
<xsl:template match="xhtml:meta">
<xsl:message>xhtml:meta</xsl:message>
</xsl:template>
<!-- identity -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
<xsl:message>identita</xsl:message>
</xsl:template>
<xsl:template match="xhtml:div[@class='sxSmall']">
<xsl:element name="div">
<xsl:attribute name="class"><xsl:value-of select="@class" /></xsl:attribute>
<xsl:apply-templates />
</xsl:element>
<xsl:message>xhtml:div</xsl:message>
</xsl:template>
</xsl:stylesheet>
-------------- UPDATE ----------------
The problem is related to Xalan and the way I put the XML source in it. The Java code follows:
StringReader srXslContent = new StringReader(xslContent);
TransformerFactory tFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl",null);
Transformer transformer = null;
try
{
transformer = tFactory.newTransformer(new StreamSource(srXslContent));
Context.getInstance().getLogger().debug("Transformer created!");
} catch (TransformerConfigurationException e)
{
Context.getInstance().getLogger().error(ExceptionUtils.getStackTrace(e));
}
StringWriter sw = new StringWriter();
Document doc = XmlUtils.parseXmlFile(xmlContent);
DOMSource domSource = new DOMSource(doc.getDocumentElement());
try
{ // Could be this?
transformer.transform(domSource, new StreamResult(sw));
// with streamsource Xalan works fine!!!
//transformer.transform(new StreamSource(new StringReader(xmlContent)), new StreamResult(sw));
Context.getInstance().getLogger().debug("Transformation made!");
} catch (TransformerException e)
{
Context.getInstance().getLogger().error(ExceptionUtils.getStackTrace(e));
}
The parseXml method is here:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(false);
dbf.setValidating(false);
// Sax
dbf.setFeature("http://xml.org/sax/features/validation", false);
// Xerces: to disable Internet searching...
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(contentToParse));
Document document =db.parse(is);
return document;
It's important to note that if I give the XML source as a String (through a StringReader and a StreamSource) it works fine with Xalan too. I'm beginning to suspect the problem is in the DOMSource...
Upvotes: 0
Views: 3795
Reputation: 5572
Try to enable namespaces for the DocumentBuilder, as I see you are using namespaces in your xslt matches. Also construct the new DOMSource with the document and not the document.getDocumentElement() method.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document d = db.parse(...);
DOMSource ds = new DOMSource(d);
Upvotes: 4
Reputation: 711
Don't see anything wrong with the XSLT, but hard to say without the XML source you are using.
But if I had to guess, I would think the problem is in the namespace. Does the source document also define and use that xhtml namespace...? And is it parsed with a namespace-aware XML parser?
Upvotes: 2