October 21, 2024
Chicago 12, Melborne City, USA
java

Different behavior of default transformer and XSLT identity transform


I have the below XML:

<?xml version="1.0"?>
<x:books xmlns:x="urn:collection" xmlns:p="urn:property">
  <book id="bk001">
    <p:author>Writer</p:author>
    <p:title>The First Book</p:title>
    <p:genre>Fiction</p:genre>
  </book>
</x:books>

which is parsed with a namespace-unaware parser:

DocumentBuilderFactory factory = DocumentBuilderFactory.newDefaultInstance(); // JDK-default implementation
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(new InputSource(new StringReader(xmlString)));

When it is converted back to string using the default identity transformer…

TransformerFactory factory = TransformerFactory.newDefaultInstance(); // JDK-default implementation
Transformer tr0 = factory.newTransformer();
Writer w0 = new StringWriter();
tr0.transform(new DOMSource(dom), new StreamResult(w0));

…I get the original XML unchanged (with all the x: and p: namespace prefixes retained).

However, when I try to use an XSLT identity transform to transform it…

<transform version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
    <output method="xml" encoding="UTF-8" indent="no" omit-xml-declaration="no" />
    <template match="*|@*|node()">
        <copy><apply-templates select="*|@*|node()" /></copy>
    </template>
</transform>
Transformer tr1 = factory.newTransformer(new StreamSource(new StringReader(xsltString)));
Writer w1 = new StringWriter();
tr1.transform(new DOMSource(dom), new StreamResult(w1));

… I get the following XML (with all namespace prefixes removed):

<?xml version="1.0" encoding="UTF-8"?><books xmlns:p="urn:property" xmlns:x="urn:collection">
  <book id="bk001">
    <author>Writer</author>
    <title>The First Book</title>
    <genre>Fiction</genre>
  </book>
</books>

Considering in my codebase I have no control over how the DOM is created (it could be namespace-aware or unaware, latter in most cases), how can I write an XSLT 1.0 transform that will always retain all XML namespace prefixes?
(Identity transform is an example, I would like to write more complex transformations in the future)

Is there any property that I can set on the TransformerFactory or any changes in the XSLT match="..." attribute that I can perform to achieve this?



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video