Hi.

We're using the Jaxp API in Java to get a content handler:

transformerFactory = (SAXTransformerFactory) 
SAXTransformerFactory.newInstance();

//Get a TransformerHandler object that can process SAX ContentHandler events
into a Result.
// The transformation is defined as an identity (or copy) transformation,
// for example to copy a series of SAX parse events into a DOM tree.

mHandler = transformerFactory.newTransformerHandler(); 

mTransformer = mHandler.getTransformer();

etc.

We write content by calling the contentHandler methods, such as

contentHandler.startElement(aNamespace, localname, qname, attributes)

This code has been working fine for years, using the standard XML SAX support in
Java.

Recently, Saxon 8 or 9 was introduced into the class path, and the Saxon
versions of the SAXTransformerFactory and TransformerHandler (Open Declaration
<eclipse-open:%E2%98%82=uimaj-core/C:%5C/Users%5C/IBM_ADMIN%5C/.m2%5C/repository%5C/net%5C/sf%5C/saxon%5C/Saxon-HE%5C/9.7.0-14%5C/Saxon-HE-9.7.0-14.jar%3Cnet.sf.saxon.jaxp%28IdentityTransformerHandler.class%E2%98%83IdentityTransformerHandler%7EIdentityTransformerHandler%7ELnet.sf.saxon.jaxp.IdentityTransformer;>net
<eclipse-javadoc:%E2%98%82=uimaj-core/C:%5C/Users%5C/IBM_ADMIN%5C/.m2%5C/repository%5C/net%5C/sf%5C/saxon%5C/Saxon-HE%5C/9.7.0-14%5C/Saxon-HE-9.7.0-14.jar%3Cnet>.sf
<eclipse-javadoc:%E2%98%82=uimaj-core/C:%5C/Users%5C/IBM_ADMIN%5C/.m2%5C/repository%5C/net%5C/sf%5C/saxon%5C/Saxon-HE%5C/9.7.0-14%5C/Saxon-HE-9.7.0-14.jar%3Cnet.sf>.saxon
<eclipse-javadoc:%E2%98%82=uimaj-core/C:%5C/Users%5C/IBM_ADMIN%5C/.m2%5C/repository%5C/net%5C/sf%5C/saxon%5C/Saxon-HE%5C/9.7.0-14%5C/Saxon-HE-9.7.0-14.jar%3Cnet.sf.saxon>.jaxp
<eclipse-javadoc:%E2%98%82=uimaj-core/C:%5C/Users%5C/IBM_ADMIN%5C/.m2%5C/repository%5C/net%5C/sf%5C/saxon%5C/Saxon-HE%5C/9.7.0-14%5C/Saxon-HE-9.7.0-14.jar%3Cnet.sf.saxon.jaxp>.IdentityTransformerHandler
<eclipse-javadoc:%E2%98%82=uimaj-core/C:%5C/Users%5C/IBM_ADMIN%5C/.m2%5C/repository%5C/net%5C/sf%5C/saxon%5C/Saxon-HE%5C/9.7.0-14%5C/Saxon-HE-9.7.0-14.jar%3Cnet.sf.saxon.jaxp%28IdentityTransformerHandler.class%E2%98%83IdentityTransformerHandler>.IdentityTransformerHandler)
were used instead. This has caused a difference in output, in which our method
of getting a default namespace to be written, has stopped working with the Saxon
version.

We are trying to serialize out a form containing start elements, lets say a, b,
and c,
**all of which belong to some namespace**,
let's call it "a-url-to-use-as-default-name-space". 

Our calls to the startElement API pass the namespace string, the element name,
the element name (again, without any namespace prefix) and attributes (if any).

As a special case, the topmost startElement API call has an attribute added to
the set of attributes with the attribute name "xmlns", and a value of
"a-url-to-use-as-default-name-space".  This previously resulted in the generated
XML something like this:

<a xmlns="a-url-to-use-as-default-name-space">
    <b ... />     
    <c ... />
</a>

When Saxon is used, we've found that it strips off the attribute
'xmlns="a-url-to-use-as-default-name-space"'.  I can even see the code snippet
that does this, when I single-stepped through the code; it's this bit, in
"ReceivingContentHandler":

public void startElement(String uri, String localname, String rawname,
Attributes atts)
            throws SAXException {
        try {
            flush(true);

            NodeName elementName = getNodeName(uri, localname, rawname);
            receiver.startElement(elementName, Untyped.getInstance(),
localLocator, ReceiverOptions.NAMESPACE_OK);

            for (int n = 0; n < namespacesUsed; n++) {
                receiver.namespace(namespaces[n], 0);
            }

            for (int a = 0; a < atts.getLength(); a++) {
                int properties = ReceiverOptions.NAMESPACE_OK;
                String qname = atts.getQName(a);
                if (qname.startsWith("xmlns") && (qname.length()==5 ||
qname.charAt(5)==':')) {
                    // We normally configure the parser so that it doesn't
notify namespaces as attributes.
                    // But when running as a TransformerHandler, we have no
control over the feature settings
                    // of the sender of the events. So we filter them out, just
in case. There might be cases
                    // where we ought not just to ignore them, but to handle
them as namespace events, but
                    // we'll cross that bridge when we come to it.
                    continue;
                }

It's the part just above, ending with continue, which discovers we've attached
an attribute "xmlns", and it skips it.

If this is correct behavior, then I'm guessing there's another way one is
supposed to use to instruct the Saxon "Identity" XSLT transformer to specify it
should use a default name space.  Can you please say what that method is?

Thanks.  -Marshall Schor

Reply via email to