Search code examples
xmlxsltxquerybasex

BaseX XSLT fails after returning first result


I have a large XML file stored in BaseX that I need to split up into smaller, modular documents. I have created an XSL file to do so:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:output indent="yes" encoding="UTF-8"/>
    <xsl:param name="schema"/>
    <xsl:param name="model"/>
    <xsl:param name="sysDiff"/>
    <xsl:param name="sys"/>
    <xsl:param name="subsys"/>
    <xsl:param name="subsubsys"/>
    <xsl:param name="assy"/>
    <xsl:param name="disassy"/>
    <xsl:param name="disassyv"/>
    <xsl:param name="info"/>
    <xsl:param name="infov"/>
    <xsl:param name="itemloc"/>
    <xsl:param name="tname"/>
    <xsl:param name="iname"/>
    <xsl:param name="outputDir"/>

    <xsl:template match="/">
        <xsl:result-document href="{concat($outputDir, '/DMC-',$model,'-',$sysDiff,'-',$sys,'-',$subsys,$subsubsys,'-',$assy,'-',$disassy,$disassyv,'-',$info,$infov,'-',$itemloc,'.xml')}" method="xml">
            <dmodule>
                <identAndStatusSection>
                    <dmAddress>
                        <dmIdent>
                            <dmCode modelIdentCode="{$model}" systemDiffCode="{$sysDiff}">
                                <xsl:attribute name="systemCode" select="$sys"/>
                                <xsl:attribute name="subSystemCode" select="$subsys"/>
                                <xsl:attribute name="subSubSystemCode" select="$subsubsys"/>
                                <xsl:attribute name="assyCode" select="$assy"/>
                                <xsl:attribute name="disassyCode" select="$disassy"/>
                                <xsl:attribute name="disassyCodeVariant" select="$disassyv"/>
                                <xsl:attribute name="infoCode" select="$info"/>
                                <xsl:attribute name="infoCodeVariant" select="$infov"/>
                                <xsl:attribute name="itemLocationCode" select="$itemloc"/>
                            </dmCode>
                            <language languageIsoCode="en" countryIsoCode="US"/>
                            <issueInfo issueNumber="000" inWork="01"/>
                        </dmIdent>
                    </dmAddress>
                </identAndStatusSection>
            </dmodule>
        </xsl:result-document>    
    </xsl:template>
</xsl:stylesheet>

My issue is that when using the xslt:transform() function in BaseX it only returns (creates) the first document. This is the XQuery I have for this:

 let $style := doc('file:///C:/base.xsl')

   for $d in doc('file:///C:/Users/tfurst/Documents/Book1-test.xml')//title
      for $newD in //*[title]
      where $newD/title/@id eq $d/@id
        let $schema := $d/schemaName
        let $model := $d/modelic
        let $sdc := $d/sdc
        let $sys := $d/systemCode
        let $subsys := $d/subsys
        let $subsubsys := $d/subsubsys
        let $assy := $d/assy
        let $disassy := $d/disassy
        let $disassyv := $d/disassyv
        let $info := $d/infoCode
        let $infov := $d/infov
        let $itemloc := $d/itemloc
        let $tname := $d/tname
        let $iname := $d/iname
        return xslt:transform($newD,$style, map {"outputDir":"file:///G:/LMA-Conv/Flight/test-conv-out", "model":$model, "sysDiff":$sdc, "sys":$sys, "subsys":$subsys, "subsubsys":$subsubsys, "assy":$assy, "disassy":$disassy, "disassyv":$disassyv, "info":$info, "infov":$infov, "itemloc":$itemloc, "tname":$tname, "iname":$iname})

The document named Book1-test.xml is essentially a map of existing IDs of elements to new output file names. After it creates the first XML output file BaseX returns ERROR [FODC0002] "" (Line 1): Premature end of file. When I looked up the error code in the BaseX documentation this error is defined as "The specified document resource cannot be retrieved. ". Is there some limitation to the use of the xslt:transform function in a loop? I am not understanding why it was able to retrieved the first time, but not after that. I have tried to move the XSL to different file locations, no luck. Am I missing something ridiculously obvious here?


Solution

  • I think Gerrit Imsieke on the BaseX mailing list has the right explanation, BaseX doesn't fail to process the second input to XSLT, it fails to convert the empty result of your first call to xslt:transform to any of its XQuery representations. So using xslt:transform-text instead should fix your problem. Or having the XSLT output a primary result with a root element.