Search code examples
xsltxqueryexist-db

XQuery chaining XSLT transformations


I am trying to transform an XML document through a series of XSL stylesheets transformations in eXist. I want to up-convert it from pubs2 to pubs9. (I need to chain the result document of one transformation into the next transformation) I have tried several different ways and I was thinking it would be something like:

let $trans1 := for $a in $stylesheet/version[@pub = '3'] return transform:transform(doc("/db/myXML.xml"), $a, ())

let $trans2 := for $b in $stylesheet/version[@pub = '4'] return transform:transform(doc($trans1), $b, ())

etc

let $trans9 := for $z in $stylesheet/version[@pub = '9'] return transform:transform(doc($trans8), $z, ())
return $trans9

But I keep getting cardinality error. Is there a different way to do it?

BTW: I am using XQuery 1.0. I hope to convert to 3.0 very soon. :)


Solution

  • You can use recursion to apply a sequence of XSLTs to a source document, chaining the output of the first to the input of the second and so on. I have written the function local:transform-pipeline below which is a general purpose function that shows how this works.

    xquery version "1.0";
    
    import module namespace transform = "http://exist-db.org/xquery/transform";
    
    declare function local:transform-pipeline($src as document-node()+, $transforms as xs:anyURI*, $params as node()?) as document-node()+ {
        if(empty($transforms))then
            $src
        else
            let $results := 
                for $s in $src
                return
                    for $result in transform:transform($s, doc($transforms[1]), $params)
                    return
                        document { $result }
            return            
                local:transform-pipeline($results, subsequence($transforms, 2), $params)
    };
    
    
    let $xslts := (xs:anyURI("/db/1.xslt"), xs:anyURI("/db/2.xslt"), xs:anyURI("/db/n.xslt"))
    return
        local:transform-pipeline(doc("/db/my-document.xml"), $xslts, ())