James,

I've been trying to figure out the best way to demonstrate the issue. The
problem is I don't have control (or great understanding) of the input XML or
the stylesheet, I'm just the middle man running the transformation. Both are
also very complex (and proprietary), but here's my attempt at clarification:


The only mention of the "missing namespaces" in the stylesheet I'm using is
in the beginning. What the stylesheet actually does is basically a mystery
to me :-)

---
<xsl:transform version="1.0" xmlns:helper="xalan://dialog.util.helper"
xmlns:java="java" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
...
...
...
---


The input file looks something like this:

---
<File621 xml:space="preserve">
    <RECORD></RECORD>
    <RECORD></RECORD>
    <RECORD></RECORD>
                ...
                ...
                ...
</File621>
---

When I run the stylesheet with the input through the plain vanilla Xalan
command line processor the output looks like this:

---
<n-load xmlns:java="java" xmlns:helper="xalan://dialog.util.helper">
    <n-document></n-document>
    <n-document></n-document>
    <n-document></n-document>
                ...
                ...
                ...
</n-load>
---

The namespaces are showing up, but when I run the transformation through my
code, this is what I get:

---
<n-load>
    <n-document></n-document>
    <n-document></n-document>
    <n-document></n-document>
                ...
                ...
                ...
</n-load>
---

The namespace definitions are missing, but otherwise the two outputs seem
identical. Below is a simplified/pruned version of the code that I'm using.
This is basically a class that builds a document object a block of records
at a time, calls an external object to style the document and then
serializes the styled results.

And yes, I'm calling writeOpen() only on the root element. 

Well, this turned out not to be exactly a "mini" example ;-) Sorry about
that, didn't mean to overwhelm you. If you can take a look and tell me what
you think, that would be great.



Thanks,

Terry





---
public class XMLRecordProcessor{
    public XMLRecordProcessor(  Reader xmlReader,
                                Writer xmlWriter,
                                String recordTag,
                                int blockSize,
                                IDocumentStyler styler)
                                throws IOException {
        
        recordTag_  = recordTag;
        blockSize_  = blockSize;
        styler_     = styler;
        recordList_ = new ArrayList();        

        logger_.debug("Processor created. (blocksize="+blockSize_+")");


        try {
            SAXReader reader = new SAXReader();
            writer_ = new XMLWriter(
                    xmlWriter, OutputFormat.createCompactFormat());
            
            xmlWriter.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        
            // Set the default handler and kick off the parsing.
            reader.setDefaultHandler(this);
            Document doc = reader.read(xmlReader);


            // Check to se if we have left over elements that still need
            // processing.
            if (recordList_.size() > 0) {
                try {
                    processBlock();
                }
                catch (Exception e) {
                }
            }            

            // Everything besides the close of the root element should
            // be by now been written out. 
            writer_.writeClose(rootElement_);

            // Flush out and close the writer and we are done.
            xmlWriter.flush();            
        }
        catch (DocumentException de) {
        }
    }

    
    public void onStart(ElementPath path) {
        
        if (!rootElementStored_) {
            rootElementStored_ = true;
            
            Element element = path.getCurrent();            
            rootElement_ = element.getDocument().getRootElement();
         
            // We also need to transform the root element.
            try {
                rootElement_ = processElement(rootElement_);
            }
            catch (Exception e) {
            }

            try {
                // TODO: Doesn't write out namespace definitions!
                writer_.writeOpen(rootElement_);
            }
            catch (IOException ioe) {
            }
        }
    }


    
    public void onEnd(ElementPath path) {
        Element element = path.getCurrent();
        
        if (element.getQualifiedName().equals(recordTag_)) {
            recordList_.add(element);

            if (recordList_.size() == blockSize_) {
                try {
                    // process the records we have gathered so far.
                    processBlock();
                }
                catch (Exception e) {
                }
            }
        }
    }


    private Element processElement(Element element)
            throws  TransformerConfigurationException, TransformerException,
                    IOException {
                
        DocumentSource source = new DocumentSource(rootElement_);
        DocumentResult result = new DocumentResult();
        
        styler_.style(source, result);

        return result.getDocument().getRootElement();
    }
    

    private void processBlock() throws  TransformerConfigurationException,
            TransformerException, IOException {
                              
        Element parent = ((Element)recordList_.get(0)).getParent();
        DocumentSource source = new DocumentSource(parent);
        DocumentResult result = new DocumentResult();
                
        styler_.style(source, result);
       
        // Write out the children of the root level node.
        Iterator i =
result.getDocument().getRootElement().elementIterator();
        while (i.hasNext()) {
            Element e = (Element)i.next();
            writer_.write(e);
        }
        
        
        // Now detach all the elements in the list.
        Iterator i2 = recordList_.iterator();
        while (i2.hasNext()) {
            Element e = (Element)i2.next();
            e.detach();
        }
        recordList_.clear();
            
    }
}
---


-----Original Message-----
From: James Strachan [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, May 01, 2002 11:11 AM
To: Wilson, Terry; 'dom4j-user'
Subject: Re: [dom4j-user] Namespaces and writeOpen()


I hear where you're going with this and generally think this is a good
strategy. I'm just trying to figure out how/where the issue is with
namespaces.Do you have a mini example of where the namespaces are and where
they are missing?

e.g. if you take an individual <RECORD> (using your example) and use it in
XSLT and then output the result of the XSLT operation via the write(Element)
method then it should all just work I think.

Just a quick question; you only need to use the writeOpen() method for the
root element right? For the results of the transformation you're using
write(Element).

e.g. in pseduo code...

XMLWriter writer = ...;
writer.writeOpen( doc.getRootElement() );

// get one record...
Element record = ...;
Document newDoc = someTransform( record );
// write the whole result ...
writer.write( newDoc.getRootElement() );

// then when we're finished...
writer.writeClose( doc.getRootElement() );


The above should, I think, output all the namespaces defined in the
transformation output nicely.

James
----- Original Message -----
From: "Wilson, Terry" <[EMAIL PROTECTED]>
To: "'James Strachan'" <[EMAIL PROTECTED]>; "'dom4j-user'"
<[EMAIL PROTECTED]>
Sent: Wednesday, May 01, 2002 6:32 PM
Subject: RE: [dom4j-user] Namespaces and writeOpen()


> I believe my problem is caused by my approach and lack of understanding of
> the technology rather than something in dom4j. Here's what I do. I have a
> document like:
>
> <RECORDSET>
>     <RECORD>data</RECORD
>     <RECORD>data</RECORD
>     <RECORD>data</RECORD
>     <RECORD>data</RECORD
> </RECORDSET>
>
> Because in real life the document is too big to hold in memory all at once
I
> need to apply XSLT in intermediate steps. I start reading in the document
> and creating the dom4j document object. Once I have the root element I
apply
> a transformation and just write the open tag of the result with
> XMLWriter.writeOpen(). I then remove the root from the document object and
> read in a block of n records into the document. I then style the document
> and serialize each record with just plain XMLWriter.write(). Finally after
> all records have been processed I do a writeClose() with the root element
to
> close the document.
>
> So the immediate problem I see is that when I am serializing the root node
> there are no other nodes in memory and no way of knowing if a namespace
> definition is actually needed. This is the first time I'm doing this so
you
> guys out there with more experience, does this problem make my approach
> invalid? Can I get around it somehow or totally rethink my strategy? Is my
> thinking just plain naive? ;-) The idea is to produce the same output that
I
> would get by applying a stylesheet to the whole dodument. When I do this,
> the namespaces do appear in the output document.
>
> I'll also take a look at writing some code to demonstrate this if I get a
> chance, but I hope you get the picture.
>
>
>
> Thanks,
>
> Terry
>
> -----Original Message-----
> From: James Strachan [mailto:[EMAIL PROTECTED]]
> Sent: Wednesday, May 01, 2002 9:51 AM
> To: Wilson, Terry; Dom4j-User (E-mail)
> Subject: Re: [dom4j-user] Namespaces and writeOpen()
>
>
> Internally XMLWriter uses a NamespaceStack to know if it needs to output
new
> namespace declarations with new nodes. It could be that the way that
you're
> using it, the XMLWriter isn't properly popping the namespace stack, so
that
> the required namespace definitions don't appear.
>
> Any chance you could create a little unit test to demonstrate the problem?
> I.e. a bit of code and a test document. Then it'd be easier to see the
> problem.
>
> If you could add an existing test method to an existing test case, such as
> in dom4j/src/test/org/dom4j/TestXMLWriter, that'd be even better! :-)
>
> James
> ----- Original Message -----
> From: "Wilson, Terry" <[EMAIL PROTECTED]>
> To: "Dom4j-User (E-mail)" <[EMAIL PROTECTED]>
> Sent: Wednesday, May 01, 2002 5:36 PM
> Subject: [dom4j-user] Namespaces and writeOpen()
>
>
> > Hi all,
> >
> > I'm a new dom4j user and have a question I could not find an answer for
> from
> > the api or other documentation.
> >
> > I have a fairly classical situation where I have a "database" type XML
> file
> > (large, up to .5GB) that has a root node that has a set or child, record
> > nodes. I need to apply XSLT transformations to this document, which I'm
> > acchieving efficiently by utilizing the excellent ElementHandler
> interface.
> > I apply the stylesheets to a chunk of records at a time, serialize the
> > results and move on to the next chunk. This seems to work fine, but I
hit
> a
> > problem with the root node, which I also need to style.
> >
> > The root node has some namespace definitions that are causing me grief.
If
> I
> > print out the transformed root node with asXML() the namespace
definitions
> > are still there, but when I use the writeOpen(rootElement) method in the
> > XMLWriter class to serialize the output, it is missing the namespace
> > definitions. Is there something special I need to do to have the
> namespaces
> > included when calling writeOpen()? The api doc says that attributes
would
> be
> > included in the writeOpen() output, but what about namespace
definitions?
> > Are they left out on purpose and if so, how can I have them included in
my
> > output?
> >
> > I've tried this with two separate daily builds, the latest I downloaded
> > yesterday (4/30/02).
> >
> > Hope I made some sense, any help appreciated.
> >
> >
> > Thanks,
> >
> > Terry
>
>
> _________________________________________________________
> Do You Yahoo!?
> Get your free @yahoo.com address at http://mail.yahoo.com


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com

_______________________________________________________________

Have big pipes? SourceForge.net is looking for download mirrors. We supply
the hardware. You get the recognition. Email Us: [EMAIL PROTECTED]
_______________________________________________
dom4j-user mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/dom4j-user

Reply via email to