Reputation: 190
i wrote a little XSL transformation to combine multiple .xml-documents into one file. For this purpose i am using the document()
function. Currently my solution is working fine, but i am asking myself if there is a more elegant way to do this.
Is there another way to load multiple files and store each of them in a variable and then process these multiple variables within xsl:copy-of
?
Here is an example of my current XSL transformation (the XSLT is part of a XPROC-pipeline and the first file gets loaded within the pipeline):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tei="http://www.tei-c.org/ns/1.0"
xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="#all">
<!-- Laden der übrigen TEI-Dateien -->
<xsl:variable name="Fig2" select="document('2_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig3" select="document('3_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig4" select="document('4_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig5" select="document('5_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig6" select="document('6_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig7" select="document('7_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig8" select="document('8_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig9" select="document('9_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig10" select="document('10_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig11" select="document('11_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig12" select="document('12_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig13" select="document('13_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig14" select="document('14_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig15" select="document('15_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig16" select="document('16_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig17" select="document('17_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig18" select="document('18_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:variable name="Fig19" select="document('19_Figuration_transformiert.xml', tei:TEI)"/>
<xsl:template match="/">
<html>
<xsl:copy-of select="."/>
<xsl:copy-of select="$Fig2"/>
<xsl:copy-of select="$Fig3"/>
<xsl:copy-of select="$Fig4"/>
<xsl:copy-of select="$Fig5"/>
<xsl:copy-of select="$Fig6"/>
<xsl:copy-of select="$Fig7"/>
<xsl:copy-of select="$Fig8"/>
<xsl:copy-of select="$Fig9"/>
<xsl:copy-of select="$Fig10"/>
<xsl:copy-of select="$Fig11"/>
<xsl:copy-of select="$Fig12"/>
<xsl:copy-of select="$Fig13"/>
<xsl:copy-of select="$Fig14"/>
<xsl:copy-of select="$Fig15"/>
<xsl:copy-of select="$Fig16"/>
<xsl:copy-of select="$Fig17"/>
<xsl:copy-of select="$Fig18"/>
<xsl:copy-of select="$Fig19"/>
</html>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 1419
Reputation: 338316
Along the lines of this (the XML document you use as input does not matter here):
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tei="http://www.tei-c.org/ns/1.0"
xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="#all">
<xsl:param name="files" select="'1_Figuration_transformiert.xml;2_Figuration_transformiert.xml;...'" />
<xsl:template match="/">
<html>
<xsl:for-each select="tokenize($files, ';')">
<xsl:copy-of select="document(.)/*" />
</xsl:for-each>
</html>
</xsl:template>
</xsl:stylesheet>
The actual list of filenames is meant to be passed in from the outside instead of being hard-coded. This makes integration into batch processes easy.
You can vary the approach. For example,
document(concat(., '_Figuration_transformiert.xml'))
. <xsl:for-each select="1 to 19">
.<xsl:param>
for them and use use<xsl:for-each select="$start to $end">
.Upvotes: 1
Reputation: 163458
You ask: Is there another way to load multiple files and store each of them in a variable and then process these multiple variables within xsl:copy-of?
Well, no: if you want 18 variables, each holding one file, then you will need 18 variable declarations. But you can achieve the same effect without having 18 variables.
Firstly, you don't need any variables at all, since each of them is only used once. You could just inline them all (replace the variable reference $Fig6
by the expression used to initialize the variable Fig6
).
Secondly, if the URIs will always be systematically named like this, then you don't need to spell them all out: you can put the names in a single variable
<xsl:variable name="figs" select="(2 to 18)!(. || '_Figuration_transformiert.xml')"/>
and then replace a reference to $Fig6
with a reference to $figs[6]
. And then of course you don't need to spell out $figs[1]
, $figs[2]
, etc: you can process them all in a loop.
(The variable declaration above is XSLT 3.0 syntax, but you can achieve the same thing in XSLT 2.0 with a bit more code).
Upvotes: 0
Reputation: 167696
If the XProc processor uses Saxon 9 as the XSLT 2 processor then you could also try whether using the collection
functions eases that ask by using e.g. <xsl:copy-of select="collection(concat(base-uri(), '?select=*_Figuration_transformiert.xml'))"/>
instead of all the separate copy-of
instructions.
See http://saxonica.com/html/documentation9.8/sourcedocs/collections.html.
Upvotes: 0