使用XSLT base-uri和Saxon集合函数

时间:2016-11-14 19:16:35

标签: xslt saxon

我想批处理目录中的所有XML文件,根据每个XML中的值生成输出文件名。我将Saxon集合函数与base-uri函数结合使用,但是我无法单独访问每个URI。

编辑:下面的样式表给出了错误消息:“不允许多个项目的序列作为base-uri()的第一个参数”

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" />
    <xsl:param name="input-dir" select="'file:///C:/path/to/directory'"/>

    <xsl:template name="main">
        <xsl:variable name="input-docs" select="collection(iri-to-uri(concat($input-dir, '?select=*.xml')))"/>
        <xsl:variable name="old-filename" select="base-uri($input-docs)"/>
        <xsl:variable name="new-filename" select="item[@name = 'LogNo']/text"/>

        <xsl:for-each select="$old-filename">
            <xsl:result-document href="concat ($new-filename, '.xml')">
                <xsl:copy-of select="."/>
            </xsl:result-document>
        </xsl:for-each>

    </xsl:template>

</xsl:stylesheet>

编辑:为了完整性,我添加了我尝试过的两个命令行提示。我不确定是否应在样式表或命令行中指定输入目录的路径。

 java -jar "C:\path\to\saxon.jar" -it:main -o:"C:\path\to\renamed\XML"  -xsl:"C:\path\to\stylesheet.xslt" 

 java -jar "C:\path\to\saxon.jar" -s:"C:\path\to\input\XML" -o:"C:\path\to\renamed\XML"  -xsl:"C:\path\to\stylesheet.xslt" 

1 个答案:

答案 0 :(得分:0)

如果您遵循始终声明变量数据类型的规则,通常会清楚您的错误在哪里。

例如,input-docs的声明显然应该有as="document-node()*"类型。但这显然不是base-uri()号召唤的有效论据。

所以很明显你的代码出了什么问题(实际上,错误信息清楚地表明了这一点)。纠正它是比较困难的,因为你没有告诉我们你想要达到的目标。但正常的逻辑是这样的:

<xsl:template name="main">
    <xsl:variable name="input-docs" 
      select="collection(iri-to-uri(concat($input-dir, '?select=*.xml')))" 
      as="document-node()*"/>
    <xsl:for-each select="$input-docs">
      <xsl:variable name="new-filename" 
                    select="item[@name = 'LogNo']/text"         
                    as="xs:string"/>
      <xsl:result-document href="concat ($new-filename, '.xml')">
        <xsl:copy-of select="."/>
      </xsl:result-document>
    </xsl:for-each>

如果你想获得集合中文档的基础uri,你可能应该在xsl中执行此操作; for-each - 但我不确定你真正想要对这些信息做什么。 (另外,使用document-uri()可能比base-uri()更合适,但区别是微妙的。)