-
Bug
-
Resolution: Fixed
-
P3
-
5.0
-
b92
-
x86
-
linux
FULL PRODUCT VERSION :
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux 2.6.5 i686 unknown
A DESCRIPTION OF THE PROBLEM :
The problem ocurs only if one of the documents declares some namespace.
Use two XML documents with some namespace declared in at least one
of them. Load one xml document with the xsl document on the command
line, and one with a call to document(). You can not refer to the
IDs in either document.
1.
If we load another xml document with a document() call, any ID references held
by the document we now have open will disappear.
The problem is fixed if we also load the main document explicitly after the
external stylesheet is loaded. The main document must be loaded by name;
using an empty string will not work.
-------------------------------------------------------------------------------
2.
IDs in a second document, loaded with a document() call, always disappear.
In the test case, the id() call even finds a node in the wrong document, with
a wrong id.
-------------------------------------------------------------------------------
This bug causes NullPointerException to be thrown in some stylesheets which
use the id() method.
The NullPointerException occurs in SAX2DTM2.java:1991
method name: _type2
Cause:
m_exptype_map is null.
Apparently it is null because it has not been initialized by a call to endDocument().
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run test app with:
javac xsltest.java
java xsltest test.xsl test.xml
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The result file, test1.html includes the output.
The file should list the @count attribute for the elements.
ACTUAL -
The @count attribute is not found. Actually, the element is not found
at all. Something is found, but what is unclear. At least in one case
a random element from the wrong document is found.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
// All 4 files are below.
// I also posted them at http://www.tksoft.com/sun/
// under "javabug4"
// xsltest.java
import java.io.File;
import java.io.IOException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.w3c.dom.Document;
public class xsltest {
static public void main (String[] argv) {
if (argv.length != 2) {
System.err.println("Usage: xslfile xmlfile.");
System.exit(-1);
}
try {
File xmlFile = new File(argv[1]);
Document document = getNewXmlDoc(xmlFile);
xmlxsl2html(new File(argv[0]), document, new File("test1.html"));
} catch (Exception ex) {
System.err.println(ex.getMessage());
ex.printStackTrace(System.err);
}
System.err.println("test1.html contains the output.");
}
static void xmlxsl2html(File xslFile, Document document, File targetfile) throws Exception {
try {
TransformerFactory tFactory = TransformerFactory.newInstance();
StreamSource stylesource = new StreamSource(xslFile);
Transformer transformer = tFactory.newTransformer(stylesource);
transformer.clearParameters();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(targetfile);
transformer.transform(source, result);
} catch (TransformerConfigurationException ex) {
throw ex;
} catch (TransformerException ex) {
throw ex;
}
}
static Document getNewXmlDoc(File xmlFile) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
try {
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setErrorHandler(new org.xml.sax.helpers.DefaultHandler() {
public void fatalError(SAXParseException e) throws SAXParseException {
throw e;
}
public void error(SAXParseException e) throws SAXParseException {
throw e;
}
public void warning(SAXParseException e) throws SAXParseException {
throw e;
}
});
return builder.parse(xmlFile);
} catch (SAXException ex) {
throw ex;
} catch (ParserConfigurationException ex) {
throw ex;
} catch (IOException ex) {
throw ex;
}
}
}
// test.xml
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE organization [
<!ELEMENT organization (company*,ids)>
<!ELEMENT company (#PCDATA | department | equipment:instance)*>
<!ELEMENT ids (id*)>
<!ELEMENT id EMPTY>
<!ELEMENT department EMPTY>
<!ELEMENT equipment:instance EMPTY>
<!ATTLIST organization id ID #IMPLIED
xmlns:equipment CDATA #FIXED "http://namespaces.tksoft.com/equipment/"
>
<!ATTLIST company id ID #REQUIRED
count CDATA #REQUIRED
>
<!ATTLIST department id ID #REQUIRED
>
<!ATTLIST equipment:instance id ID #REQUIRED
>
<!ATTLIST id
value IDREF #REQUIRED
>
]>
<organization>
<company id="ca" count="2">
<department id="da"/>
<equipment:instance id="ea"/>
<equipment:instance id="eb"/>
</company>
<company id="cb" count="0">
</company>
<company id="cc" count="5">
</company>
<ids>
<id value="ca"/>
<id value="cb"/>
</ids>
</organization>
// test2.xml
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE organization2 [
<!ELEMENT organization2 (company*,ids)>
<!ELEMENT company (#PCDATA | department)*>
<!ELEMENT ids (id*)>
<!ELEMENT id EMPTY>
<!ELEMENT department EMPTY>
<!ATTLIST organization id ID #IMPLIED
>
<!ATTLIST company id ID #REQUIRED
count CDATA #REQUIRED
>
<!ATTLIST department id ID #REQUIRED
>
<!ATTLIST id
value IDREF #REQUIRED
>
]>
<organization2>
<company id="xca" count="2">
<department id="xda"/>
</company>
<company id="xcb" count="0">
</company>
<company id="xcc" count="5">
</company>
<ids>
<id value="xca"/>
<id value="xcb"/>
</ids>
</organization2>
// test.xsl
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:equipment="http://namespaces.tksoft.com/equipment/"
>
<xsl:variable name="companies" select="//company"/>
<xsl:variable name="ids" select="//ids//id"/>
<xsl:variable name="dummy" select="document('test2.xml')"/>
<!--
Comment out this dummy2 line to make ids disappear from the main document as well.
-->
<xsl:variable name="dummy2" select="document('test.xml')"/>
<xsl:template match="/">
Test to make id maps disappear. Bug exists in jdk 5.0, not in j2se 1.4.
The following ids disappear only if dummy2 is commented out:
<xsl:apply-templates select="$ids"/>
The following ids always disappear:
<xsl:apply-templates select="$dummy//ids/id"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="id">
<!-- the context node is the id element. The @value attribute refers to an id
in the same document, so it should be found. The rules for id() say that
the ids which are searched are those in the document of the context node.
-->
<xsl:variable name="entity" select="id(@value)"/>
Entity id: <xsl:value-of select="@value"/>,
match count: <xsl:value-of select="count($entity)"/>,
match tagname: <xsl:value-of select="name($entity)"/>,
attrs: <xsl:value-of select="$entity/@*"/>,
count attr: <xsl:value-of select="$entity/@count"/>
</xsl:template>
</xsl:stylesheet>
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Don't load documents with document() if they contain IDs. Load such
documents as the primary document. Load documents without IDs
with document(), and lastly add a redundant call to document()
to load the primary document.
###@###.### 2004-12-09 17:04:54 GMT
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux 2.6.5 i686 unknown
A DESCRIPTION OF THE PROBLEM :
The problem ocurs only if one of the documents declares some namespace.
Use two XML documents with some namespace declared in at least one
of them. Load one xml document with the xsl document on the command
line, and one with a call to document(). You can not refer to the
IDs in either document.
1.
If we load another xml document with a document() call, any ID references held
by the document we now have open will disappear.
The problem is fixed if we also load the main document explicitly after the
external stylesheet is loaded. The main document must be loaded by name;
using an empty string will not work.
-------------------------------------------------------------------------------
2.
IDs in a second document, loaded with a document() call, always disappear.
In the test case, the id() call even finds a node in the wrong document, with
a wrong id.
-------------------------------------------------------------------------------
This bug causes NullPointerException to be thrown in some stylesheets which
use the id() method.
The NullPointerException occurs in SAX2DTM2.java:1991
method name: _type2
Cause:
m_exptype_map is null.
Apparently it is null because it has not been initialized by a call to endDocument().
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run test app with:
javac xsltest.java
java xsltest test.xsl test.xml
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The result file, test1.html includes the output.
The file should list the @count attribute for the elements.
ACTUAL -
The @count attribute is not found. Actually, the element is not found
at all. Something is found, but what is unclear. At least in one case
a random element from the wrong document is found.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
// All 4 files are below.
// I also posted them at http://www.tksoft.com/sun/
// under "javabug4"
// xsltest.java
import java.io.File;
import java.io.IOException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.w3c.dom.Document;
public class xsltest {
static public void main (String[] argv) {
if (argv.length != 2) {
System.err.println("Usage: xslfile xmlfile.");
System.exit(-1);
}
try {
File xmlFile = new File(argv[1]);
Document document = getNewXmlDoc(xmlFile);
xmlxsl2html(new File(argv[0]), document, new File("test1.html"));
} catch (Exception ex) {
System.err.println(ex.getMessage());
ex.printStackTrace(System.err);
}
System.err.println("test1.html contains the output.");
}
static void xmlxsl2html(File xslFile, Document document, File targetfile) throws Exception {
try {
TransformerFactory tFactory = TransformerFactory.newInstance();
StreamSource stylesource = new StreamSource(xslFile);
Transformer transformer = tFactory.newTransformer(stylesource);
transformer.clearParameters();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(targetfile);
transformer.transform(source, result);
} catch (TransformerConfigurationException ex) {
throw ex;
} catch (TransformerException ex) {
throw ex;
}
}
static Document getNewXmlDoc(File xmlFile) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
try {
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setErrorHandler(new org.xml.sax.helpers.DefaultHandler() {
public void fatalError(SAXParseException e) throws SAXParseException {
throw e;
}
public void error(SAXParseException e) throws SAXParseException {
throw e;
}
public void warning(SAXParseException e) throws SAXParseException {
throw e;
}
});
return builder.parse(xmlFile);
} catch (SAXException ex) {
throw ex;
} catch (ParserConfigurationException ex) {
throw ex;
} catch (IOException ex) {
throw ex;
}
}
}
// test.xml
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE organization [
<!ELEMENT organization (company*,ids)>
<!ELEMENT company (#PCDATA | department | equipment:instance)*>
<!ELEMENT ids (id*)>
<!ELEMENT id EMPTY>
<!ELEMENT department EMPTY>
<!ELEMENT equipment:instance EMPTY>
<!ATTLIST organization id ID #IMPLIED
xmlns:equipment CDATA #FIXED "http://namespaces.tksoft.com/equipment/"
>
<!ATTLIST company id ID #REQUIRED
count CDATA #REQUIRED
>
<!ATTLIST department id ID #REQUIRED
>
<!ATTLIST equipment:instance id ID #REQUIRED
>
<!ATTLIST id
value IDREF #REQUIRED
>
]>
<organization>
<company id="ca" count="2">
<department id="da"/>
<equipment:instance id="ea"/>
<equipment:instance id="eb"/>
</company>
<company id="cb" count="0">
</company>
<company id="cc" count="5">
</company>
<ids>
<id value="ca"/>
<id value="cb"/>
</ids>
</organization>
// test2.xml
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE organization2 [
<!ELEMENT organization2 (company*,ids)>
<!ELEMENT company (#PCDATA | department)*>
<!ELEMENT ids (id*)>
<!ELEMENT id EMPTY>
<!ELEMENT department EMPTY>
<!ATTLIST organization id ID #IMPLIED
>
<!ATTLIST company id ID #REQUIRED
count CDATA #REQUIRED
>
<!ATTLIST department id ID #REQUIRED
>
<!ATTLIST id
value IDREF #REQUIRED
>
]>
<organization2>
<company id="xca" count="2">
<department id="xda"/>
</company>
<company id="xcb" count="0">
</company>
<company id="xcc" count="5">
</company>
<ids>
<id value="xca"/>
<id value="xcb"/>
</ids>
</organization2>
// test.xsl
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:equipment="http://namespaces.tksoft.com/equipment/"
>
<xsl:variable name="companies" select="//company"/>
<xsl:variable name="ids" select="//ids//id"/>
<xsl:variable name="dummy" select="document('test2.xml')"/>
<!--
Comment out this dummy2 line to make ids disappear from the main document as well.
-->
<xsl:variable name="dummy2" select="document('test.xml')"/>
<xsl:template match="/">
Test to make id maps disappear. Bug exists in jdk 5.0, not in j2se 1.4.
The following ids disappear only if dummy2 is commented out:
<xsl:apply-templates select="$ids"/>
The following ids always disappear:
<xsl:apply-templates select="$dummy//ids/id"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="id">
<!-- the context node is the id element. The @value attribute refers to an id
in the same document, so it should be found. The rules for id() say that
the ids which are searched are those in the document of the context node.
-->
<xsl:variable name="entity" select="id(@value)"/>
Entity id: <xsl:value-of select="@value"/>,
match count: <xsl:value-of select="count($entity)"/>,
match tagname: <xsl:value-of select="name($entity)"/>,
attrs: <xsl:value-of select="$entity/@*"/>,
count attr: <xsl:value-of select="$entity/@count"/>
</xsl:template>
</xsl:stylesheet>
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Don't load documents with document() if they contain IDs. Load such
documents as the primary document. Load documents without IDs
with document(), and lastly add a redundant call to document()
to load the primary document.
###@###.### 2004-12-09 17:04:54 GMT