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.

Reply via email to