2017-06-18 76 views
0

我有两个文件夹包含两个相同数字的文件列表。迭代通过两个并行集合并输出第三个

**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 

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

在其他wordds,我有一个XSLT样式表,我可以成功运行,比如说,Folder_XX/xx_file1.xml,它使用从它的等效文件中的其他文件夹中的document('Folder_YY/yy_file1_bkabka.xlf')手段一些内容。我需要为所有文件做同样的事情。

我能想到一个办法:

  • 重命名Folder_YY因此,所有文件的名称相匹配的Folder_XX
  • 其相应文件给输入文件名的样式表从document('Folder_YY/$inputFileName')获取内容
  • 迭代中的输入文件Folder_XX从命令行在每个文件上运行样式表。

但是,也许在XSLT中可以从样式表中更有效地做到这一点?例如当从命令行运行样式表时,提供两个文件夹的路径作为参数?

通过文件在列表中的位置递归获取文件将是理想的,但如果不行的话,重命名文件夹Folder_YY,但这不是问题。

结果文件可以命名为输入文件,可能带有一个后缀,如_out.xml,例如,输入:Folder_XX/xx_file1.xml - >输出:Folder_XX_Out/xx_file1_out.xml。

我将不胜感激任何提示或建议。

UPDATE

这是我将运行作为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> 

与Final样式表UPDATE

<?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:variable name="output-name" select="replace(
      tokenize(document-uri(/), '/')[last()], 
      '(.+)\.xml', 
      '$1_out.xml' 
     )"/> 
     <xsl:result-document href="output-folder/{$output-name}"> 
      <xsl:apply-templates/> 
     </xsl:result-document> 
    </xsl:template> 

    <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-input" select="replace(
      replace($input-uri, 'Folder_XX', 'Folder_YY'), 
      'xx_(file[0-9]+)\.xml', 
      'yy_$1.xml' 
     )"/> 
     <xsl:copy-of select="key('ref', ../@id, doc($secondary-input))/source" /> 
    </xsl:template> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

您使用哪种XSLT处理器?或者您可以使用哪种XSLT处理器?例如使用像Saxon 9这样的XSLT 2.0处理器, 'collection('Folder_XY?select = xx_file * .xml')''''''''''''''''''''''''''''''我目前不确定是否要从所有文件中生成单个转换结果,或者是否要生成多个转换结果,但后者在XSLT 2.0中也可以使用'xsl:result-document'。 –

+0

如果你显示你现有的代码,特别是匹配根节点'/'或根元素'/ *',这也会有帮助。 –

+0

我在XSLT 2.0中使用SaxonHE 9.7.0.15。转换的输出应该为每个输入文件看到一个输出文件,因此另一个文件夹的文件与输入文件夹(xx)中包含的文件一样多。 – msoutopico

回答

1

为了处理使用撒克逊从命令行单个文件,而无需硬编码辅助文件的文件名可以使用

<?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> 
+0

谢谢,马丁。我认为你理解了这件事,所以你的代码应该可以工作。我已经将你的建议添加到了我的样式表中,我通过创建系统环境变量向_JAVA_OPTIONS添加了更多的内存,并且使用'java -jar saxonb9-1-0-8j/saxon9.jar -it:main - xsl:my.xsl '。唉,我得到这个错误:'XTDE1270:无法调用key()函数,当没有上下文项目(它正在尝试使用ref键),我认为你可能会很熟悉(检查https ://sourceforge.net/p/saxon/mailman/message/28208487/)。有小费吗? – msoutopico

+0

我明白'main'模板中使用的'collection'函数遍历文件夹中的文件并将每个文件发送到'input-uri'变量,所以在获取集合和使用每个输入文件之间没有其他的链接是需要。 – msoutopico

+0

我无法在具有“匹配”属性的模板中解释错误消息,所以我不确定哪里出错。由于评论中的代码交换困难,您可能需要编辑您的问题并显示您现在拥有的完整样式表。 –

相关问题