I figured this out, I think. To add a default namespace, before the first startElement call, do a content-handler startPrefixMapping call, passing as arguments:
the prefix: "" -- this makes it the "default" prefix the uri: whatever uri your using for the default namespace in subsequent calls to startElement. The good news is that this approach also works for non-Saxon cases. -Marshall On 12/12/2016 10:12 PM, Marshall Schor wrote: > 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 >