使用 XSL 文档加载多个文件并将它们存储在单独的变量中
Load multiple files with XSL document and store them in separate variables
我写了一点 XSL 转换来将多个 .xml-文档合并到一个文件中。为此,我正在使用 document()
函数。目前我的解决方案运行良好,但我在问自己是否有更优雅的方法来做到这一点。
是否有另一种方法可以加载多个文件并将每个文件存储在一个变量中,然后在 xsl:copy-of
中处理这些多个变量?
这是我当前 XSL 转换的示例(XSLT 是 XPROC 管道的一部分,第一个文件在管道中加载):
<?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>
沿着这条线(您用作输入的 XML 文档在这里无关紧要):
<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>
实际的文件名列表是从外部传入的,而不是硬编码的。这使得集成到批处理过程变得容易。
您可以改变方法。例如,
- 如果所有文档的后缀相同,可以列一个数字列表,使用
document(concat(., '_Figuration_transformiert.xml'))
。
- 如果有固定数量的文件,并且没有数字之间的差距,你可以使用
<xsl:for-each select="1 to 19">
.
- 如果循环的开始和结束是可变的,你可以为它们制作
<xsl:param>
并使用 use
<xsl:for-each select="$start to $end">
.
如果 XProc 处理器使用 Saxon 9 作为 XSLT 2 处理器,那么您还可以尝试使用 collection
函数是否可以通过使用例如<xsl:copy-of select="collection(concat(base-uri(), '?select=*_Figuration_transformiert.xml'))"/>
而不是所有单独的 copy-of
指令。
参见http://saxonica.com/html/documentation9.8/sourcedocs/collections.html。
你问:是否有另一种方法可以加载多个文件并将每个文件存储在一个变量中,然后在 xsl:copy-of 内处理这些多个变量?
嗯,不:如果你想要 18 个变量,每个变量保存一个文件,那么你将需要 18 个变量声明。但是不用18个变量也可以达到同样的效果
首先,您根本不需要任何变量,因为每个变量只使用一次。您可以将它们全部内联(将变量引用 $Fig6
替换为用于初始化变量 Fig6
的表达式)。
其次,如果 URI 总是像这样系统地命名,那么您不需要将它们全部拼写出来:您可以将名称放在一个变量中
<xsl:variable name="figs" select="(2 to 18)!(. || '_Figuration_transformiert.xml')"/>
然后将对 $Fig6
的引用替换为对 $figs[6]
的引用。然后当然你不需要拼出 $figs[1]
、$figs[2]
等:你可以在一个循环中处理它们。
(上面的变量声明是 XSLT 3.0 语法,但您可以在 XSLT 2.0 中使用更多代码实现同样的事情)。
我写了一点 XSL 转换来将多个 .xml-文档合并到一个文件中。为此,我正在使用 document()
函数。目前我的解决方案运行良好,但我在问自己是否有更优雅的方法来做到这一点。
是否有另一种方法可以加载多个文件并将每个文件存储在一个变量中,然后在 xsl:copy-of
中处理这些多个变量?
这是我当前 XSL 转换的示例(XSLT 是 XPROC 管道的一部分,第一个文件在管道中加载):
<?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>
沿着这条线(您用作输入的 XML 文档在这里无关紧要):
<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>
实际的文件名列表是从外部传入的,而不是硬编码的。这使得集成到批处理过程变得容易。
您可以改变方法。例如,
- 如果所有文档的后缀相同,可以列一个数字列表,使用
document(concat(., '_Figuration_transformiert.xml'))
。 - 如果有固定数量的文件,并且没有数字之间的差距,你可以使用
<xsl:for-each select="1 to 19">
. - 如果循环的开始和结束是可变的,你可以为它们制作
<xsl:param>
并使用 use
<xsl:for-each select="$start to $end">
.
如果 XProc 处理器使用 Saxon 9 作为 XSLT 2 处理器,那么您还可以尝试使用 collection
函数是否可以通过使用例如<xsl:copy-of select="collection(concat(base-uri(), '?select=*_Figuration_transformiert.xml'))"/>
而不是所有单独的 copy-of
指令。
参见http://saxonica.com/html/documentation9.8/sourcedocs/collections.html。
你问:是否有另一种方法可以加载多个文件并将每个文件存储在一个变量中,然后在 xsl:copy-of 内处理这些多个变量?
嗯,不:如果你想要 18 个变量,每个变量保存一个文件,那么你将需要 18 个变量声明。但是不用18个变量也可以达到同样的效果
首先,您根本不需要任何变量,因为每个变量只使用一次。您可以将它们全部内联(将变量引用 $Fig6
替换为用于初始化变量 Fig6
的表达式)。
其次,如果 URI 总是像这样系统地命名,那么您不需要将它们全部拼写出来:您可以将名称放在一个变量中
<xsl:variable name="figs" select="(2 to 18)!(. || '_Figuration_transformiert.xml')"/>
然后将对 $Fig6
的引用替换为对 $figs[6]
的引用。然后当然你不需要拼出 $figs[1]
、$figs[2]
等:你可以在一个循环中处理它们。
(上面的变量声明是 XSLT 3.0 语法,但您可以在 XSLT 2.0 中使用更多代码实现同样的事情)。