You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xalan.apache.org by ja...@petrobras.com.br on 2003/08/27 21:50:15 UTC

unexpected behaviour processing a branch with DOM

Hi.

I have a issue with the DOM processing and couldn't find related topics in
the archives. Perhaps someone could provide some help.

As part a web service (I use Axis), I am extracting a branch of the SOAP
body and using it as input to Xalan.
I am using a DOMSource initialized with my root element parent node, as
required by DOMSource's constructor. It lloks like this:

         Element base = ... (find the element which is to be used as the
root);
         DOMSource xml = new DOMSource( base.getParentNode() );

base's parent node is a simple element, whith a single child, base itself.
The transformation runned smothly, but the results showed the although the
base element was correctly matched and processed, the template matching "/"
was not processed. According to DOMSource javadoc, it should have been.

I tried to use a new element instead of the actual parent, as in

         Node fakeRoot = base.getOwnerDocument().createElement("dummy");
         fakeRoot.appendChild(base);
         DOMSource xml = new DOMSource( fakeRoot );

The result was exactly the same: the "/" templated was not executed, its
child (the base element) was executed instead. In despair, a tried to usa a
DocumentFragment instead, as in:

         Node fakeRoot = base.getOwnerDocument().createDocumentFragment();
         fakeRoot.appendChild(base);
         DOMSource xml = new DOMSource( fakeRoot );

Now everything worked as expected, the "/" template was executed and the
output was OK.

Can somebody explain me why this is so? Shouldn't all three solutions
produce the same result? I'm trying to understand what I did wrong and why
only the third solution worked, because similar situations will appear in
other web services.

Thank in advance,

=============================================
Marcelo Jaccoud Amaral
Petrobras - IT - e-business Division
mailto:jaccoud [at] petrobras.com.br
=============================================
There are only 10 kinds of people in the world: those who understand binary
and those who don't.




Re: unexpected behaviour processing a branch with DOM

Posted by Dave Flanagan <da...@trainingetc.com>.
Hello jaccoud,

In order to attempt to clarify what you are seeing I am going to start by
trying to convince you to be very careful of your use of the word "root"
when speaking about XML.

I do this because I have seen it time and time again be used in such a way
that it leads to automatic confusion when speaking of XSLT in my experience.

Many people refer to the first Element in an XML document as the "root element"
of the XML document. When an element is described as a node, these same people
then naturally begin to think of this first element as the root node, and
then begin to think of   "/" as representing the first element inside of an
XML document.

To avoid this confusion it may be better to only ever refer to the first
element within an XML document as the   "document element", and ONLY use
the term "root" to refer to the "/" used within a memory based model such
as the DOM or XSLT's tree model.

With this said - in a DOM structure - the "root" can be thought of as equivalent
to an object of type org.w3.dom.Document in the DOM. The first element in the
XML document is actually a child node of the Document.

So if the Node being passed to the DOMSource constructor is NOT a Document object
the node being passed to the stylesheet via the transform method will NEVER be
processed by the <xsl:template match="/"> element in your stylesheet.

The reason your last test worked with a DocumentFragment is because - as is
stated in the javadocs:
         DocumentFragment is a "lightweight" or "minimal" Document object
         
So it IS treated as if it were a Document and therefore would match "/".


If in your first example Element base was equal to the "document element"
then base.getParentNode() would have been the Document object and "/" would
have been matched in your stylesheet.

You wrote:
        Element base = ... (find the element which is to be used as the root);
        DOMSource xml = new DOMSource( base.getParentNode() );
        
I will use a sample XML document shown below to try to walk you through
what you are seeing happen:

       <?xml version="1.0"?>
       <library>
         <book>
           <title>A Title</title>
         </book>
       </library>
       
If Element base were to be the "title" node shown above
then the book node would have been the parameter passed
to the DOMSource constructor since you called the
getParentNode on title

So your when the transform takes place the "book" node
is a single node in the node set that is made available
for processing by the stylesheet.

Because of this it would be handled by a template matching
"book" instead of what you may have expected - a template
that matches "/".


so your base is not a child of the Document object
but merely the child of an Element that is basically
a descendant of the Document.

Hope I explained in such a way that it makes sense

just remeber to be careful not to think of the first
element as the "root" and don't think of "/" as the
first element. If you think of "/" as a Document object
it may help clear up some confusion

Dave Flanagan




Wednesday, August 27, 2003, 3:50:15 PM, you wrote:

jpcb> Hi.

jpcb> I have a issue with the DOM processing and couldn't find related topics in
jpcb> the archives. Perhaps someone could provide some help.

jpcb> As part a web service (I use Axis), I am extracting a branch of the SOAP
jpcb> body and using it as input to Xalan.
jpcb> I am using a DOMSource initialized with my root element parent node, as
jpcb> required by DOMSource's constructor. It lloks like this:

jpcb>          Element base = ... (find the element which is to be used as the
jpcb> root);
jpcb>          DOMSource xml = new DOMSource( base.getParentNode() );

jpcb> base's parent node is a simple element, whith a single child, base itself.
jpcb> The transformation runned smothly, but the results showed the although the
jpcb> base element was correctly matched and processed, the template matching "/"
jpcb> was not processed. According to DOMSource javadoc, it should have been.

jpcb> I tried to use a new element instead of the actual parent, as in

jpcb>          Node fakeRoot = base.getOwnerDocument().createElement("dummy");
jpcb>          fakeRoot.appendChild(base);
jpcb>          DOMSource xml = new DOMSource( fakeRoot );

jpcb> The result was exactly the same: the "/" templated was not executed, its
jpcb> child (the base element) was executed instead. In despair, a tried to usa a
jpcb> DocumentFragment instead, as in:

jpcb>          Node fakeRoot = base.getOwnerDocument().createDocumentFragment();
jpcb>          fakeRoot.appendChild(base);
jpcb>          DOMSource xml = new DOMSource( fakeRoot );

jpcb> Now everything worked as expected, the "/" template was executed and the
jpcb> output was OK.

jpcb> Can somebody explain me why this is so? Shouldn't all three solutions
jpcb> produce the same result? I'm trying to understand what I did wrong and why
jpcb> only the third solution worked, because similar situations will appear in
jpcb> other web services.

jpcb> Thank in advance,

jpcb> =============================================
jpcb> Marcelo Jaccoud Amaral
jpcb> Petrobras - IT - e-business Division
jpcb> mailto:jaccoud [at] petrobras.com.br
jpcb> =============================================
jpcb> There are only 10 kinds of people in the world: those who understand binary
jpcb> and those who don't.