迭代两个并行集合并输出第三个集合

时间:2017-06-18 13:05:48

标签: xml loops xslt iteration directory

我有两个文件夹,其中包含两个相同数字的相同文件列表。

**Folder_XX:**
- xx_file1.xml
- xx_file2.xml
... 
- xx_fileN.xml

**Folder_YY:**
- yy_file1_bkabka.xml
- yy_file2_blabla.xml
... 
- yy_fileN_zedzed.xml

对于第一个文件夹中的每个文件,我需要使用第二个文件夹中等效文件中的数据进行转换。

在其他文章中,我有一个可以成功运行的XSLT样式表,例如 Folder_XX / xx_file1.xml ,它通过{使用其他文件夹中的等效文件中的一些内容{1}}。我需要为所有文件做同样的事情。

我可以想到一种方法:

  • 重命名 Folder_YY 中的所有文件,使其名称与 Folder_XX
  • 中的等效文件相匹配
  • 将输入文件的名称提供给样式表以从document('Folder_YY/yy_file1_bkabka.xlf')
  • 获取内容
  • 通过 Folder_XX 中的输入文件,从命令行中逐句运行每个样式表。

但是,也许在XSLT中,可以从样式表中更高效地完成它?例如从命令行运行样式表时,提供两个文件夹的路径作为参数?

按照列表中的位置递归获取文件将是理想的,但如果不可能,则重命名 Folder_YY 中的文件,但这不是问题。

结果文件可以命名为输入文件,可能带有document('Folder_YY/$inputFileName')之类的后缀,例如input:Folder_XX / xx_file1.xml - >输出:Folder_XX_Out / xx_file1_out.xml。

我会对任何提示或建议表示感谢。

更新

这是我将作为_out.xml运行的样式表。

java -jar saxon9he.jar Folder_XX/xx_file1.xml my.xsl

使用最终样式表更新

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
    <xsl:strip-space elements="*"/>

    <!-- this fetches the source node from the yy file -->
    <xsl:key name="ref" match="trans-unit" use="@id"/> 
    <xsl:template match="source">
        <xsl:copy-of select="key('ref', ../@id, document('Folder_YY/yy_file1_bkabka.xml'))/source" />
    </xsl:template>

    <!-- everything else comes from the the xx file -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

要从命令行使用Saxon处理单个文件,而不必硬编码您可以使用的辅助文件的文件名

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
    <xsl:strip-space elements="*"/>

    <xsl:variable name="input-uri" select="document-uri(/)"/>
    <xsl:variable name="secondary-uri" select="replace(replace($input-uri, 'Folder_XX', 'Folder_YY'), 'xx_(file[0-9+)\.xml', 'yy_($1)_bkabka.xml')"/>

    <!-- this fetches the source node from the yy file -->
    <xsl:key name="ref" match="trans-unit" use="@id"/> 
    <xsl:template match="source">
        <xsl:copy-of select="key('ref', ../@id, doc($secondary-input))/source" />
    </xsl:template>

    <!-- everything else comes from the the xx file -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

如果你想处理一组文件,我会从命名模板开始,例如-it:main并使用

<xsl:template name="main">
  <xsl:apply-templates select="collection('Folder_XX?select=xx_file*.xml')"/>
</xsl:template>

然后

<xsl:template match="/">
  <xsl:result-document href="output-folder/result{position()}.xml">
   <xsl:apply-templates/>
  </xsl:result-document>
</xsl:template>

(计算出的输出文件名只是一个例子,你当然可以使用输入文件名的一部分),然后你需要像以前一样计算文件名,只在

    <xsl:template match="source">
        <xsl:variable name="input-uri" select="document-uri(/)"/>
        <xsl:variable name="secondary-uri" select="replace(replace($input-uri, 'Folder_XX', 'Folder_YY'), 'xx_(file[0-9+)\.xml', 'yy_($1)_bkabka.xml')"/>
        <xsl:copy-of select="key('ref', ../@id, doc($secondary-input))/source" />
    </xsl:template>

所以你最终应该

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
    <xsl:strip-space elements="*"/>

 <xsl:template name="main">
  <xsl:apply-templates select="collection('Folder_XX?select=xx_file*.xml')"/>
</xsl:template>

<xsl:template match="/">
  <xsl:result-document href="output-folder/result{position()}.xml">
   <xsl:apply-templates/>
  </xsl:result-document>
</xsl:template>

    <!-- this fetches the source node from the yy file -->
    <xsl:key name="ref" match="trans-unit" use="@id"/> 

    <xsl:template match="source">
        <xsl:variable name="input-uri" select="document-uri(/)"/>
        <xsl:variable name="secondary-uri" select="replace(replace($input-uri, 'Folder_XX', 'Folder_YY'), 'xx_(file[0-9+)\.xml', 'yy_($1)_bkabka.xml')"/>
        <xsl:copy-of select="key('ref', ../@id, doc($secondary-input))/source" />
    </xsl:template>

    <!-- everything else comes from the the xx file -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>