Probably best to nail down the problem in a bug report first, providing
XML input, XSLT stylesheet, actual and expected XML output to
demonstrate the problem.
Now if https://bugs.openjdk.org/browse/JDK-8168664 describes your problem:
The Xalan version bundled with the JDK /afaik/ seems to get occasional
security updates and improvements but does not reflect the latest Xalan
version.
Latest Xalan 2.7.3 does not show the problematic behaviour of
JDK-8168664, so a possible workaround would be to not rely on the XSLT
processor bundled with the JDK but instead use Xalan or Saxon directly.
Best,
Johannes
On 23/04/2025 16:03, Hempushpa Sahu wrote:
Problem Description :
XSLT transformation creating unique namespace prefixes.
Analysis & Observation :
The XSLT transformation is generating a new namespace prefix for every
XML element, even when the namespace value matches that of the parent
element. This leads to large XML file transformations exceeding the
file size and memory limits on our systems.
The behaviour in OpenJDK has remained consistent since JDK 8; however,
the namespace prefix issue is not something we find optimum.
During our investigation of the OpenJDK codebase, we identified defect
https://bugs.openjdk.org/browse/JDK-8167179, which was intended to
resolve the namespace prefix issue in the OpenJDK 8 release. However,
our testing confirms that the issue persists across multiple versions,
including OpenJDK 8, 11, 17, and 22. Additionally, we found an open
bug report https://bugs.openjdk.org/browse/JDK-8168664 in the OpenJDK
issue tracker referencing a similar problem. Notably, there has been
no recent activity on this bug for several years
Suggested Solution:
Introduced a hashmap, and storing the unique namespace-url from root
node and checking if new url namespace-url encountered then we will
store it in the hashmap and increment the namespace prefix, else we
will not increment the prefix.
Implemented in existing function startXslElement() of
src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java
else {
// Need to generate a prefix?
if (namespace != null && namespace.length() > 0) {
prefix = generatePrefix();
qname = prefix + ':' + qname;
handler.startElement(namespace, qname, qname);
handler.namespaceAfterStartElement(prefix, namespace);
}
The above code is changed to
else {
// Need to generate a prefix?
if (namespace != null &&
namespace.length() > 0) {
//Check if prefix needs to be incremented.
if (!namespaceMap.containsKey(namespace))
{
namespaceMap.put(namespace,
threadLocalPrefixIndex.get().getAndIncrement());
prefix = "ns"+namespaceMap.get(namespace);
qname = prefix + ':' + qname;
handler.startElement(namespace, qname, qname);
handler.namespaceAfterStartElement(prefix, namespace);
}
else
{
//Namespace URI already exist in map.
prefix = "ns"+namespaceMap.get(namespace);
qname = prefix + ':' + qname;
handler.startElement(namespace, qname, qname);
handler.namespaceAfterStartElement(prefix, namespace);
}
}
Releases:
OpenJDK 8, 11, 17 & 22 the issue is seen.
Note:
Proceeding with this approach, we will need to update the test files.
For instance, we have identified one test case that validates the
namespace prefix in the result -
test/jaxp/javax/xml/jaxp/unittest/transform/NamespacePrefixTest.java
Next steps:
We want to take the above-mentioned fix to OpenJDK.
Please review and suggest if the above understanding is right and we
shall take the fix to OpenJDK.