transform results are missing namespace declarations

View: New views
4 Messages — Rating Filter:   Alert me  

transform results are missing namespace declarations

by bkc :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I looked at http://exist.sourceforge.net/xquery.html#serialization, but
none of those options look like they will fix my problem.

I'm generating a .xslt file "on the fly".

The generated xsl, when made using command-line xalan, has a root
element like this:

        <xsl_:stylesheet
xmlns:xsl_="http://www.w3.org/1999/XSL/Transform" xmlns:const="const.uri"
            xmlns:tal="http://xml.zope.org/namespaces/tal"
            xmlns:metal="http://xml.zope.org/namespaces/metal"
            exclude-result-prefixes="tal metal const" version="1.0">  


But when executing the transform within eXist, the generated stylesheet
root element is this:

<xsl_:stylesheet xmlns:xsl_="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="tal metal const" version="1.0">  


How can I get eXist's transform() to retain the namespaces that I need?
I need

xmlns:const="const.uri"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"


The tal2xslt.xsl stylesheet has this root element:

<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:exslt="http://exslt.org/common" xmlns:const="const.uri"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:bxf="http://bitflux.org/functions"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:func="http://exslt.org/functions" xmlns:xsl_="whatever"
version="1.0" extension-element-prefixes="func exslt"
exclude-result-prefixes="bxf xhtml">

It does not ask for tal: or metal: namespaces to be excluded.



--
Brad Clements,                bkc@...    (315)268-1000
http://www.murkworks.com                         
AOL-IM: BKClements


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Exist-open mailing list
Exist-open@...
https://lists.sourceforge.net/lists/listinfo/exist-open

Re: transform results are missing namespace declarations

by bkc :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Just a quick follow up on this.

The generated output from the first transform step does not reference
those missing namespaces at all.

So the command line xalan doesn't have to include them, and it looks
like xalan embedded in eXist is excluding 'unreferenced' namespaces.

But the real problem is that turning around and using the generated
output (stylesheet) and another transform in the same xquery causes
xalan to complain about a missing namespace.

That's why I first assumed that the namespace declarations where required.

So this query fails, but should work:

        xquery version "1.0";

        declare namespace xmldb="http://exist-db.org/xquery/xmldb";
        declare namespace util="http://exist-db.org/xquery/util";
        declare namespace transform="http://exist-db.org/xquery/transform";

        let $tal2xslt_dir_path := '/db/ATALi/tal2xslt/tal2xslt/xsl',
            $metal_and_tal_stylesheet := doc(concat($tal2xslt_dir_path,
'/metal_and_tal.xsl')),
            $metal_stylesheet := doc(concat($tal2xslt_dir_path,
'/metal.xsl')),
            $tal2xslt_stylesheet := doc(concat($tal2xslt_dir_path,
'/tal2xslt.xsl'))

        let $source_template := doc('master.htm')
        let $parameters := <parameters><param
name="tal_global_variables" value="url_prefix ''"/></parameters>
        let $stylesheet := transform:transform(
              transform:transform($source_template,
                  $metal_stylesheet,
                  $parameters
              ),
              $tal2xslt_stylesheet,
              $parameters)

        let $source := doc('test.xml')
        return transform:transform($source,
            $stylesheet,
            ()
        )  

The error is:

An exception occurred during query execution: A SAX exception occurred
while compiling the stylesheet: Can not resolve namespace prefix: tal
[at line 23, column 8] [at line 23, column 8]

(line 23 is the last transform call in the xquery file)

So for some reason, xalan in xquery thinks that the tal namespace is
needed for the 3rd transform, even though it is not.

Perhaps the exclude-result-prefixes="tal metal const"  on the generated
stylesheet element is causing xalan to foul up. It should ignore
undeclared namespaces in this case.



--
Brad Clements,                bkc@...    (315)268-1000
http://www.murkworks.com                         
AOL-IM: BKClements


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Exist-open mailing list
Exist-open@...
https://lists.sourceforge.net/lists/listinfo/exist-open

transform / document('') in stylesheet, DatabaseResolver doesn't handle it

by bkc :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Still chipping away on getting tal2xslt working inside eXist.

One common thing I need to support is having the stylesheet read itself
for configuration data.

So, the html template looks like:

        <div tal:omit-tag="" tal:repeat="file
document('')//const:javascript/const:file">
            <script type="text/javascript" tal:attributes="src
concat($url_prefix, '/scripts/', $file)"/>
        </div>

tal2xslt translates that into the following xsl:

                <xsl_:for-each
select="document('')//const:javascript/const:file">
                    <xsl_:variable select="." name="file"/>
                    <script type="text/javascript">
                        <xsl_:attribute name="src">
                            <xsl_:value-of select="concat($url_prefix,
'/scripts/', $file)"/>
                        </xsl_:attribute>
                    </script>
                </xsl_:for-each>


Using xalan from the command line, this works fine. document('') is
supported correctly.

However trying to do this from within eXist produces the following error
in the server log:

     SystemId Unknown; Line #0; Column #0; java.lang.NullPointerException


Googling around, I came across this post (from 2001).

http://www.stylusstudio.com/xsllist/200111/post30040.html

It suggests that xalan does not keep a 'regular' DOM copy of the
stylesheet to refer to later when handling document('').

I was creating the xsl through a transform, then passing that xsl node
directly into transform, like this:

let $source_template := doc('master.htm')
let $parameters := <parameters><param name="tal_global_variables"
value="url_prefix ''"/></parameters>
let $stylesheet := transform:transform(
      transform:transform($source_template,
          $metal_stylesheet,
          $parameters
      ),
      $tal2xslt_stylesheet,
      $parameters)

let $source := doc('test.xml')
return transform:transform($source,
    $stylesheet,
    ()
)

Then I thought maybe this is the cause of the problem with xalan, it
cannot "re-read" its stylesheet source in the last transform when
resolving document('').

So I changed the code to cache the stylesheet, but it still does not work:

let $stylesheet_path := xmldb:store('/db/byways/test/cache',
'sheet.xsl', $stylesheet)
 
let $source := doc(concat($base, '/test.xml'))
let $stylesheet := doc(concat('xmldb:exist://', $stylesheet_path))

return transform:stream-transform($source,
    $stylesheet,
    ()
)

I've looked at Transform.Java and maybe  DatabaseResolver is not right,
about line 498 in Transform.java

I see this error in logs:

2008-07-16 21:32:01,658 [SocketListener0-2] DEBUG (Transform.java
[resolve]:508) - Document  not found in collection /db/byways/test/cache

I tried to fix this up without really knowing what I'm doing, I changed  
Transform.java like this (around line 429, DatabaseResolver class):

        public Source resolve(String href, String base)
            throws TransformerException {
            Collection collection = doc.getCollection();
            //TODO : use dedicated function in XmldbURI
            LOG.debug("DatabaseResolver.resolve href='"+href+"',
base='"+base+"'");
            if("" == href || 0 == href.length()) {
                // document('') should return the stylesheet source itself
                LOG.debug("DatabaseResolver.resolve returning xsl
document");
                return new DOMSource(doc);
            } else {
                String path;
                DocumentImpl xslDoc;
                if(href.startsWith("/"))
                    path = href;
                else
                    path = collection.getURI() + "/" + href;
                try {
                    xslDoc = (DocumentImpl)
context.getBroker().getXMLResource(XmldbURI.create(path));
                } catch (PermissionDeniedException e) {
                    throw new TransformerException(e.getMessage(), e);
                }
                if(xslDoc == null) {
                    LOG.debug("Document " + href + " not found in
collection " + collection.getURI());
                    return null;
                }
                if(!xslDoc.getPermissions().validate(context.getUser(),
Permission.READ))
                    throw new TransformerException("Insufficient
privileges to read resource " + path);
               
                DOMSource source = new DOMSource(xslDoc);
                return source;
            }
        }

The transform still fails, I see this in the log:

2008-07-16 22:20:39,117 [SocketListener0-4] DEBUG
(TransformerFactoryAllocator.java [getTransformerFactory]:98) - Set
transformer factory: org.apache.xalan.processor.TransformerFactoryImpl

2008-07-16 22:20:39,125 [SocketListener0-4] DEBUG (NativeSerializer.java
[serializeToReceiver]:107) - serializing document 71
(/db/byways/test/cache/sheet.xsl) to SAX took 7

2008-07-16 22:20:39,147 [SocketListener0-4] DEBUG (NativeSerializer.java
[serializeToReceiver]:107) - serializing document 64
(/db/byways/test/test.xml) to SAX took 0

2008-07-16 22:20:39,150 [SocketListener0-4] DEBUG (Transform.java
[resolve]:496) - DatabaseResolver.resolve href='', base='null'
2008-07-16 22:20:39,151 [SocketListener0-4] DEBUG (Transform.java
[resolve]:499) - DatabaseResolver.resolve returning xsl document
2008-07-16 22:20:39,151 [SocketListener0-4] DEBUG (Transform.java
[resolve]:496) - DatabaseResolver.resolve href='null', base='null'
2008-07-16 22:20:39,154 [SocketListener0-4] DEBUG (XQuery.java
[execute]:220) - Execution took 477 ms


also SystemId Unknown; Line #0; Column #0;
java.lang.NullPointerException is in the log file, just thrown out there
w/o a timestamp.

So it seems my "fix" isn't correct, but I think this is where the
problem is.

What's the right fix?


--
Brad Clements,                bkc@...    (315)268-1000
http://www.murkworks.com                         
AOL-IM: BKClements


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Exist-open mailing list
Exist-open@...
https://lists.sourceforge.net/lists/listinfo/exist-open

Re: transform results are missing namespace declarations

by bkc :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Brad Clements wrote:
>
> Perhaps the exclude-result-prefixes="tal metal const"  on the generated
> stylesheet element is causing xalan to foul up. It should ignore
> undeclared namespaces in this case.
>
>
>  
Just to confirm. In transform:transform, if  
xsl:stylesheet/@exclude-result-prefixes
contains a namespace prefix that is *not* in the source xml, the
transform fails in eXist, but works using xalan from the command line.

This seems like a crazy limitation in xalan. It shouldn't care about
trying to exclude result prefixes that just aren't used.




--
Brad Clements,                bkc@...    (315)268-1000
http://www.murkworks.com                         
AOL-IM: BKClements


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Exist-open mailing list
Exist-open@...
https://lists.sourceforge.net/lists/listinfo/exist-open
LightInTheBox - Buy quality products at wholesale price