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?
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.