将 XSLT 2.0 函数 iri-to-uri 替换为来自通过 Java 传入的参数的 URI 列表

Replacing the XSLT 2.0 function iri-to-uri with a list of URI's from a parameter passed in via Java

我有一些 XSL 文件可以递归地处理目录中的所有文件,基本上它读取一个名为 collection 的变量:

<xsl:variable name="collection">
        <xsl:copy-of select="collection(iri-to-uri('./?select=*.xml;recurse=yes'))/*"/>
    </xsl:variable>

然后,我们有类似的东西:

<xsl:for-each-group     select="$collection/configuration/services/service" group-by="serviceKey" >

这有一段时间没问题,但现在我想传入一个文件列表,这些文件将构成变量集合。我正在使用 java,因此我可以有效地传递以逗号分隔的文件路径或 URI 列表,但我不确定如何在 XSL 文件中处理它,以便它像递归 iri- 一样填充集合变量to-uri 函数正在运行。

如果您想将文档列表从您的环境传递到样式表,请使用一系列文档节点:

<xsl:param name="docs" as="document-node()+"/>

如果您更喜欢只传递它们的 URI,则使用字符串序列(或者可能是 xs:anyURI):

<xsl:param name="uris" as="xs:string+"/>
<xsl:param name="docs" select="$uris ! doc(.)"/>

如果您想传递一个集合 URI 列表,就像您在示例中使用的那样,给出一个目录和一个文件名模式(这是解析集合 URI 的 Saxon 方式),那么请改用以下内容:

<xsl:param name="uris" as="xs:string+"/>
<xsl:param name="docs" select="$uris ! collection(.)"/>

请注意,在上面的最后 2 个代码片段中,将 $docs 定义为参数,默认值取决于另一个参数,使用户能够直接传递 docs 的值(一系列文档节点),或者改为传递它们的 URI(不过,如果你想为它接受一个空序列,你必须将 xs:string+ 更改为 xs:string*)。

如果你希望环境能够传递文档节点、文档URI和集合URI,并结合它们,那么:

<xsl:param name="uris"  as="xs:string*"/>
<xsl:param name="colls" as="xs:string*"/>
<xsl:param name="docs"  as="document-node()*"/>

<xsl:variable name="my-docs" select="
   $uris ! doc(.), $colls ! collection(.), $docs"/>

PS:您的示例中不需要 iri-to-uri()

PS二:注意运算符!是3.0。如果您不能使用它,请使用 for $uri in $uris return doc($uri) 而不是 $uris ! doc(.)

另一种解决方案是在您的 Java 应用程序中实施 CollectionURIResolver。您可以在 运行 转型之前将此提名给 Saxon。当您调用 collection() 函数时,Saxon 将调用您的 CollectionURIResolver,它可以传回文档或 URI 列表。

http://www.saxonica.com/documentation/index.html#!javadoc/net.sf.saxon.lib/CollectionURIResolver