使用xslt确定目录中的文件

使用xslt确定目录中的文件,xslt,xslt-2.0,Xslt,Xslt 2.0,我正在替换许多元数据记录中的分发部分,以包括对其他非xml文件的可选引用。每个xml元数据记录都在一个单独的文件夹中,在每个这样的文件夹中可能有PDF文档,也可能没有Excel文件。这三个文件有独立的名称。我基本上需要一个目录列表,我可以访问和操作它 <xsl:strip-space elements="*" /> <xsl:template match="gmd:distributionInfo" > <gmd:distributionInfo>

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

<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>
下面是我一直在尝试的部分,尽管目前它确实使用Kernow Saxon 9PE编译。第一部分似乎构造了到所需子目录的正确路径,尽管带有“file:/”前缀。
我的问题是:

<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>
  • 我是否需要继续努力来确定路径?(似乎是“unxsl-ish”)。Kernow很容易在每个子目录中找到metadata.xml文件
  • 我认为我的“for each”语句不正确。在它确实执行的版本中,我临时将“select=”限制为“select=*.xml”(并且它只执行metadata.xml文件)
  • 如果没有提到的覆盖,我会得到“变量文件名尚未声明(或其声明不在范围内)”
  • <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>
    

    <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>
    
    
    
    虚拟元数据记录将作为附件

    <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>
    
    
    56400C76-E5E3-44D7-904C-90B97858F7CE
    
    对于x语句中的$i,您无法在xpath
    之外访问定义的
    $filename

    <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>
    
    尝试对代码进行以下更改:

    <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>
    
    <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(.)
    将为您提供每个文档节点的文件名

    <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文件,我将使用
    select='*.xml'
    ,因为如果目录中有其他文件,则该语句将失败

    这是相当不清楚的。请显示所需输出和实际输出,并解释什么不起作用。
    <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>