【问题标题】:Replacing the XSLT 2.0 function iri-to-uri with a list of URI's from a parameter passed in via Java用通过 Java 传入的参数中的 URI 列表替换 XSLT 2.0 函数 iri-to-uri
【发布时间】:2015-06-23 06:36:05
【问题描述】:

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

<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 函数一样填充集合变量正在工作。

【问题讨论】:

  • 请注意,您可以简单地使用 &lt;xsl:variable name="collection" select="collection(...)"/&gt; 而不是 &lt;xsl:variable name="collection"&gt;&lt;xsl:copy-of select="collection(...)"/&gt;&lt;/xsl:variable&gt;,这应该更有效,因为它会在您的代码创建已解析文档的副本时加载和解析文档一次。

标签: java xml xslt saxon


【解决方案1】:

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

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

【讨论】:

  • 嗨,迈克尔,感谢您的回答。它工作得很好。创建了一个 CollectionURIResolver,它接收文件列表并将它们转换为通过 resolve 方法返回的 AnyURIValue 对象列表。
【解决方案2】:

如果要将环境中的文档列表传递给样式表,请使用文档节点序列:

<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 的撒克逊方式),请改用以下内容:

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

请注意,在上面的最后2个代码sn-ps中,将$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 II:注意运算符! 是3.0。如果不能使用,请使用for $uri in $uris return doc($uri),而不是$uris ! doc(.)

【讨论】:

  • 感谢 Florent 的回答...所以如果我通过我的 Java 代码提供一个名为 uris 的参数,这是一个逗号分隔的 URI 列表,但是如何使用 知道如何将 URI 解析为不同的文件吗?抱歉,我的 XSLT 知识非常基础 :(
  • 为什么要它成为一个字符串来解析?你不传递什么字符串序列?如果现在的问题是如何使用 API“xyz”(例如 Saxon S9API)将字符串序列传递给参数,我会提出一个新问题。
  • 我认为答案应该指出 ! 运算符是 XPath 3.0 的一部分,因此即使使用 Saxon,它也仅适用于 Saxon 9.6 和 version="3.0" 样式表。
  • Florent,我不知道文件列表有多长,这取决于之前在 Java 代码中所做的工作。基本上,我希望从我的 java 代码中为 XSLT 文件提供一个参数。但由于该文件列表可能是 1 或 100 个文件,我需要解析它吗?我不认为这是一个单独的问题,尽管我确实编辑了标题以从中删除 Java,所以我可能会将其添加回...
  • 我的样式表版本是 2.0
猜你喜欢
  • 2011-09-27
  • 1970-01-01
  • 2016-11-22
  • 1970-01-01
  • 2010-12-11
  • 2012-10-07
  • 2010-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多