2017-06-18 102 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

我無法在具有「匹配」屬性的模板中解釋錯誤消息,所以我不確定哪裏出錯。由於評論中的代碼交換困難,您可能需要編輯您的問題並顯示您現在擁有的完整樣式表。 –

相關問題