使用xslt确定目录中的文件

时间:2014-06-02 19:32:36

标签: xslt xslt-2.0

我正在替换我的许多元数据记录中的Distribution部分,以包含对其他非xml文件的可选引用。每个xml元数据记录都在一个单独的文件夹中,并且在每个这样的文件夹中,可能有也可能不是PDF文档,也可能是Excel文件。这三个文件具有独立的名称。我基本上需要一个目录列表,我可以访问和操作。

以下是我尝试过的一个子集,尽管现在它使用Kernow-Saxon 9PE进行编译。第一部分似乎构造了所需子目录的正确路径,尽管带有“file:/”前缀 我的问题是:

  1. 我是否需要努力确定路径? (似乎是“un-xsl-ish”)。 Kernow可以在每个子目录中轻松找到metadata.xml文件。
  2. 我认为我的“for-each”陈述不正确。在它执行的版本中,我暂时将“select = ”限制为“select = * .xml”(并且它只执行metadata.xml文件)。
  3. 如果没有提到覆盖,我会收到“变量文件名尚未声明(或其声明不在范围内)”
  4.          

    <xsl:strip-space elements="*" />
    
    <xsl:template match="gmd:distributionInfo" >
        <gmd:distributionInfo>
            <gmd:distributorTransferOptions>
                <!-- construct path to directory containing xml metadata and non-xml files -->
               <xsl:variable name="pathParts" select="tokenize(base-uri(),'/') " />
                <!-- remove filename.extension, reconstruct path -->
                <xsl:variable name="directory" select="string-join((remove($pathParts,count($pathParts))),'/')" />
                <gmd:dir>
                    <gco:CharacterString>
                        <xsl:value-of select = "$directory" />
                    </gco:CharacterString>
                </gmd:dir>
                <!-- loop thru all files to obtain filenames -->
                <xsl:for-each select="for $filename in collection(concat($directory, select='*.*')) return $filename " >
                    <!-- temporary? override to enable xslt compilation -->
                    <xsl:variable name="filename" select= "base-uri()" />
                    <gmd:name>
                        <gco:CharacterString>
                            <xsl:value-of select= "$filename" />
                        </gco:CharacterString>
                    </gmd:name>
                </xsl:for-each>
            </gmd:distributorTransferOptions>
        </gmd:distributionInfo>
    </xsl:template>
    
    <xsl:template match="*" >
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>
    
    </xsl:transform>
    

    虚拟元数据记录将附加。

    <?xml version="1.0" encoding="UTF-8"?>
    <gmd:MD_Metadata xmlns:gco="http://www.isotc211.org/2005/gco"  xmlns:gmd="http://www.isotc211.org/2005/gmd">
        <gmd:fileIdentifier>
            <gco:CharacterString>56400C76-E5E3-44D7-904C-90B97858F7CE</gco:CharacterString>
        </gmd:fileIdentifier>
        <gmd:identificationInfo>
            <gmd:MD_DataIdentification>
            </gmd:MD_DataIdentification>
        </gmd:identificationInfo>
        <gmd:distributionInfo>
            <gmd:MD_Distribution>
            </gmd:MD_Distribution>
        </gmd:distributionInfo>
    </gmd:MD_Metadata>
    

1 个答案:

答案 0 :(得分:0)

您无法访问xpath $filename语句之外的已定义for $i in x

尝试对您的代码进行以下更改:

<xsl:for-each select="for $filename in collection(concat($directory, select='*.*')) return $filename " >
            <gmd:name>
                <gco:CharacterString>
                    <xsl:value-of select= "base-uri(.)" />
                </gco:CharacterString>
            </gmd:name>
</xsl:for-each>

for-each中的select语句应返回集合中每个项目的文档节点,base-uri(.)将为每个文档节点提供文件名。

此外,如果您的集合中只有xml文件,我会使用select='*.xml',因为如果您的目录中有其他文件,该语句将失败。