You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Adam Ratcliffe <ad...@premasys.com> on 2004/06/15 01:02:31 UTC

Custom Transformer: attributes lost when serialized XML recording

I have a custom transformer that extends AbstractSaxTransformer for
making XML-RPC
calls.  It extracts a method call element from an input document and
sends this to
the remote service for processing.

My problem is that when I use the startSerializedXMLRecording() method
from
AbstractSaxTransformer to collect the method call fragment it records
elements
only and the namespace attribute on the top-level element is lost.

This isn't a problem with the generator that creates the input document
as I can
see the attributes if I serialize the document after generation.

Is there a configuration step that I'm missing?




public void startElement(String uri, String name, String raw, Attributes
attr)
 throws SAXException {
 if (name.equals(XMLRPC_REQUEST_ELEMENT)) {
     this.stack.push("end");
 } else if (name.equals(XMLRPC_SERVICE_ELEMENT)){
            this.startTextRecording();     
 } else if (name.equals(XMLRPC_METHOD_CALL_ELEMENT)) {
 
this.startSerializedXMLRecording(XMLUtils.defaultSerializeToXMLFormat(tr
ue));     
 } else {
            super.startElement(uri, name, raw, attr);
        }
    }


RE: Custom Transformer: attributes lost when serialized XML recording

Posted by Adam Ratcliffe <ad...@premasys.com>.
To clarify my original problem, it's just the namespace declaration that
is lost
during serialized XML recording.  As far as I can tell this is related
to Xalan's
behaviour in that it considers namespace nodes as distinct from
attribute nodes
and therefore doesn't pass them in the attribute list to startElement().

I had a look at AbstractTextSerializer which has a pipe that preserves
namespace
declarations and used this as the basis for extending the DOMBuilder
class used for
XML recording in AbstractSAXTransformer.

What I'm doing is collecting the namespace declarations in a map in
startPrefixMapping()
and using these in startElement() to create new attributes for each
declaration which are
added to the attribute list that's passed to the parent class'
startElement() implementation.

This approach works fine, when I finish recording I have a
DocumentFragment with the namespace
declaration preserved on the root element.

I'm now having a few problems getting this XML back into the pipeline,
I'm a little new to SAX so
maybe I'm missing the obvious. Firstly I'm calling
XMLUtils.serializeNode() method on the DocumentFragment
and in this method the TransformerHandler is dropping the namespace
declaration off once more.

My 2nd problem is in understanding how pass the serialized document to
the next XMLConsumer in the pipeline.

I've tried the following code snippet (from CIncludeTransformer) which
results in nothing being output by
the serializer in the pipeline.

	    XMLDeserializer deserializer = null;
	    try {
		deserializer =
(XMLDeserializer)this.manager.lookup(XMLDeserializer.ROLE);
		deserializer.setConsumer(this.xmlConsumer);
		deserializer.deserialize(response.getBytes("UTF-8"));
	    } catch (Exception ignore) {
	    } finally {
		this.manager.release( deserializer );
	    }

Thanks in advance
Adam

-----Original Message-----
From: Vadim Gritsenko [mailto:vadim@reverycodes.com] 
Sent: Wednesday, 16 June 2004 12:10 a.m.
To: dev@cocoon.apache.org
Subject: Re: Custom Transformer: attributes lost when serialized XML
recording


Adam Ratcliffe wrote:

>I have a custom transformer that extends AbstractSaxTransformer for 
>making XML-RPC calls.  It extracts a method call element from an input 
>document and sends this to the remote service for processing.
>
>My problem is that when I use the startSerializedXMLRecording() method 
>from AbstractSaxTransformer to collect the method call fragment it 
>records elements only and the namespace attribute on the top-level 
>element is lost.
>
>This isn't a problem with the generator that creates the input document

>as I can see the attributes if I serialize the document after 
>generation.
>
>Is there a configuration step that I'm missing?
>  
>

I think you should maintain map of namespace declarations (by processing

start/end namespace mapping event) and declare all namespaces when you 
start recording. Look around for code samples, I think there is 
something similar in other transformers.

Vadim


>public void startElement(String uri, String name, String raw, 
>Attributes
>attr)
> throws SAXException {
> if (name.equals(XMLRPC_REQUEST_ELEMENT)) {
>     this.stack.push("end");
> } else if (name.equals(XMLRPC_SERVICE_ELEMENT)){
>            this.startTextRecording();     
> } else if (name.equals(XMLRPC_METHOD_CALL_ELEMENT)) {
> 
>this.startSerializedXMLRecording(XMLUtils.defaultSerializeToXMLFormat(t
r
>ue));     
> } else {
>            super.startElement(uri, name, raw, attr);
>        }
>    }
>
>
>  
>




Re: Custom Transformer: attributes lost when serialized XML recording

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Adam Ratcliffe wrote:

>I have a custom transformer that extends AbstractSaxTransformer for
>making XML-RPC
>calls.  It extracts a method call element from an input document and
>sends this to
>the remote service for processing.
>
>My problem is that when I use the startSerializedXMLRecording() method
>from
>AbstractSaxTransformer to collect the method call fragment it records
>elements
>only and the namespace attribute on the top-level element is lost.
>
>This isn't a problem with the generator that creates the input document
>as I can
>see the attributes if I serialize the document after generation.
>
>Is there a configuration step that I'm missing?
>  
>

I think you should maintain map of namespace declarations (by processing 
start/end namespace mapping event) and declare all namespaces when you 
start recording. Look around for code samples, I think there is 
something similar in other transformers.

Vadim


>public void startElement(String uri, String name, String raw, Attributes
>attr)
> throws SAXException {
> if (name.equals(XMLRPC_REQUEST_ELEMENT)) {
>     this.stack.push("end");
> } else if (name.equals(XMLRPC_SERVICE_ELEMENT)){
>            this.startTextRecording();     
> } else if (name.equals(XMLRPC_METHOD_CALL_ELEMENT)) {
> 
>this.startSerializedXMLRecording(XMLUtils.defaultSerializeToXMLFormat(tr
>ue));     
> } else {
>            super.startElement(uri, name, raw, attr);
>        }
>    }
>
>
>  
>


RE: Custom Transformer: attributes lost when serialized XML recording

Posted by Adam Ratcliffe <ad...@premasys.com>.
Some further investigation shows that this is the default behaviour of
the SAX parser to not pass in the
namespace attribute with the rest of the element attributes in
startElement().

I set the parser namespace-prefixes feature property to 'true' in
cocoon.xconf to allow the namespace
attribute to be passed through.

I'm still not seeing the namespace attribute when I output the document
fragment from endSerializedXMLRecording().

Any ideas?

Cheers
Adam

-----Original Message-----
From: Adam Ratcliffe [mailto:adam@premasys.com] 
Sent: Tuesday, 15 June 2004 11:03 a.m.
To: dev@cocoon.apache.org
Subject: Custom Transformer: attributes lost when serialized XML
recording


I have a custom transformer that extends AbstractSaxTransformer for
making XML-RPC calls.  It extracts a method call element from an input
document and sends this to the remote service for processing.

My problem is that when I use the startSerializedXMLRecording() method
from AbstractSaxTransformer to collect the method call fragment it
records elements only and the namespace attribute on the top-level
element is lost.

This isn't a problem with the generator that creates the input document
as I can see the attributes if I serialize the document after
generation.

Is there a configuration step that I'm missing?




public void startElement(String uri, String name, String raw, Attributes
attr)
 throws SAXException {
 if (name.equals(XMLRPC_REQUEST_ELEMENT)) {
     this.stack.push("end");
 } else if (name.equals(XMLRPC_SERVICE_ELEMENT)){
            this.startTextRecording();     
 } else if (name.equals(XMLRPC_METHOD_CALL_ELEMENT)) {
 
this.startSerializedXMLRecording(XMLUtils.defaultSerializeToXMLFormat(tr
ue));     
 } else {
            super.startElement(uri, name, raw, attr);
        }
    }