XSLT:如何从某个目录获取文件名?

问题描述 投票:0回答:5

XSLT 中是否有一个函数可以接受目录路径并返回其中的所有文件??

我现在有一个 xml 文件,如下所示

<filelist>
    <file>fileA.xml</file>
    <file>fileB.xml</file>
</filelist>

现在,有一个名为

dir
的目录,其中包含文件
fileX.xml
fileY.xml
和一堆其他 xml 文件。我想将这些文件添加到原始的 xml 文件中,这样我就可以获得:

<filelist>
    <file>fileA.xml</file>
    <file>fileB.xml</file>
    <file>fileX.xml</file>
    <file>fileY.xml</file>
    .... <!-- other files -->
</filelist>

有 XSLT 方法可以做到这一点吗?接受目录根目录并能够迭代其中的所有文件的东西?然后我就可以这样称呼:

<xsl:element name = file >
     <xsl:copy> <!--whatever file name--> <xsl:copy>
</xsl:element>0

[编辑解决方案]

所有的答案都非常有帮助。我最终找到了一个外部解决方案(使用撒克逊)。我认为在这里发布我的解决方案可能会对其他人有所帮助,尽管它非常适合我自己的情况。

我使用 Ant 构建一个 java web 应用程序,需要在部署之前翻译一些 xml 文件。因此,我使用

xslt
任务通过在类路径中添加“saxon9.jar”来完成这项工作。在我的 xsl 文件中,我只是做了这样的事情:

<xsl:for-each select="collection('../dir/?select=*.xml')" >
     <xsl:element name='file'>
        <xsl:value-of select="tokenize(document-uri(.), '/')[last()]"/>
     </xsl:element>
</xsl:for-each>
xml xslt file filesystems
5个回答
4
投票

XSLT 没有内置任何内容来完成此任务。 XSLT 是一种转换语言 - 对于动态输出,您通常需要一个包含所有内容(只是形式不同)的转换 - 您不能从无到有创建 XML。

解决问题的三种方法是:

  1. 用编程语言构建 XML,完全省略 XSLT。这是获得您想要的结果的最简单方法。
  2. 构建一个接受参数的 XSL 样式表,将(预构建的)分隔文件列表放入该参数中,让 XSLT 处理该字符串并从中生成 XML。这也涉及外部处理,基本上这是选项 1。此外,您还必须编写一个 XSL 样式表来执行字符串处理(XSL 尚未适应的东西)
  3. 使用扩展函数并在 XSL 中进行目录处理。如何开始的示例可以在我对此问题的回答中找到。这不是很便携,因为扩展功能是特定于平台的。

归结为:

  • 需要外部编程语言的帮助
  • 您并不绝对需要 XSLT 确实可以完成任务,因为 XML 输出就是您所需要的,不需要任何转换。

因此:不要为此使用 XSL。


1
投票

您无法在本机 XSLT 中做到这一点,但各种实现允许您添加功能扩展。

例如,在 C# 中,您可以添加用户定义的 URN:

 <xsl:stylesheet {snipped the usual xmlns stuff}
    xmlns:user="urn:user" >

然后使用“用户”中的功能

  <xsl:value-of select="user:getdirectory( @mydir )" />

在 C# 中,将“用户”关联到 C# 类:

 XSLThelper xslthelper      = new XSLThelper( );  // your class here
 xslArgs.AddExtensionObject( "urn:user", xslthelper );

并且您的类定义了“getdirectory”函数:

public class XSLThelper
{
public string getdirectory(System.Xml.XPath.XPathNavigator xml, string strXPath, string strNULL)
{
       //blah
    }
}

这里还有大量的作业! MSDN 资源


1
投票

这个问题已经六岁了并且得到了回答。 只是把我的 2 美分捐给那些再次登陆这里的人。

我需要一个表示目录中文件名的 XML 文件。我用三种方法做到了:

  1. XSLT 2.0 document() 正如其他人在此线程中指出的那样。缺点是性能,因为它将文件读入 dom 解析器,而您真正想要的只是名称。另外,正如 LarsH 在 OP 注释中指出的那样,这只适用于有效的 XML 文件。如果递归中存在非 xml 或格式错误的 xml 文件,则会导致转换崩溃。

  2. 工具 xmlstarlet 以及命令

    xmlstarlet ls > filenames.xml

  3. 我编写的一个粗略的 bash 脚本(可以优化):

目录=$1
结果文件=$2

# 将目录列表放入临时文件中
# 根据需要修改 ls 命令
ls -A1 $DIRECTORY > /tmp/zFiles.txt

# 去除碎屑并将线条包裹在  元素中
sed -i -e's/^[^$]*$/ /' /tmp/zFiles.txt

# 构建文件
回声''> $RESULTFILE
回声“”>> $RESULTFILE
猫 /tmp/zFiles.txt >> $RESULTFILE
回声“”>> $RESULTFILE

我已经使用bash脚本很长时间了,但现在我只使用xmlstarlet方法。 结果小星文件包含特定的文件属性,例如权限和日期,我发现这很有帮助。


0
投票

您应该能够使用 document() 函数读取 XML 文件。不过,我不确定各种 XSLT 引擎对它的支持情况如何。

这是一个很好的例子展示了它的使用情况。

但这并没有解决从目录中读取文件名的问题。另一个答案给出了一种实现这方面的方法。


0
投票

如果您使用 Saxon 的商业版本,则可以使用

file:list()
。这是 EXPath 文件模块的扩展函数。有关详细信息,请参阅 https://www.saxonica.com/html/documentation11/functions/expath-file/list.html
file:list()
提供一系列字符串,您可以执行类似的操作

<xsl:for-each select="file:list($path-to-dir, false())">
    <file><xsl:value-of select="."/></file>
</xsl:for-each>
© www.soinside.com 2019 - 2024. All rights reserved.