2012-04-05 56 views
1

我想要執行以下操作: 此時我們會收到一些xml文件,其中某些xml標記被錯誤填充。 爲了幫助我們的合作伙伴,我們希望通過使用「Pass-through」文件夾捕獲這些錯誤值,其中所有xml文件都放在我們的應用程序導入之前。檢查某些值和變換的xml標記 - 最佳實踐

此文件夾將被閱讀每X分鐘,每個文件將有需要做一些檢查,如:一個標籤內的值的長度,標籤的值等

因爲這只是一個臨時解決方案,我們不想在我們的應用程序中實現它。

我想的是2個可能的調校:

  • 使用Java和調用一個XSLT文件轉換的所有文件,並把它在另一個文件夾
  • 只使用Java來檢查XML文件並做轉型。 這兩種情況都會由每運行X分鐘的.bat調用。

現在我的問題:

  • 你認爲這將是最好的解決辦法? a.k.a.最快,最安全等等(可能是建議之外的東西?)
  • 你能否也提供一些例子來說明如何做這樣的事情?

我不像其他人嚴格要求密碼。如果你能給我類似的東西,我可以自己做。 在撰寫本文時,我已經在尋找其他網站上的解決方案,但由於它很緊急,所以向社區提出問題也很有幫助。

謝謝您的回答, 親切的問候, 馬騰

編輯:兩個答案對我幫助很大。感謝你們。

回答

1

如果你想運行XSLT,使用.BAT腳本,在給定的每一個XML文件文件夾(您在OP中的第一個選項)我可以想到3種方式:


答:基本上做一個「for」循環來處理每個單獨的文件通過命令行。 (好惡。)


B.使用collection()指向輸入文件夾,並使用xsl:result-document在一個新的文件夾中創建輸出文件。

下面是一個例子XSLT 2.0(與撒克遜9測試):

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:param name="pInputDir" select="'input'"/> 
    <xsl:param name="pOutputDir" select="'output'"/> 
    <xsl:variable name="vCollection" select="collection(concat($pInputDir,'/?*.xml'))"/> 

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

    <xsl:template match="/"> 
    <xsl:for-each select="$vCollection"> 
     <xsl:variable name="vOutFile" select="tokenize(document-uri(document(.)),'/')[last()]"/> 
     <xsl:result-document href="{concat($pOutputDir,'/',$vOutFile)}"> 
     <xsl:apply-templates/> 
     </xsl:result-document> 
    </xsl:for-each>  
    </xsl:template> 

</xsl:stylesheet> 

注:

該樣式表只是做一個恆等變換。它通過不變的方式傳遞XML。您需要通過添加新模板來執行檢查/更改來覆蓋身份模板。

另請注意,輸入和輸出文件夾名稱有2個參數。

使用collection()可能會遇到內存問題,因爲它會將文件夾中的所有XML文件加載到內存中。如果這是一個問題,見下文......


C.讓你的XSLT處理目錄中的所有文件的列表。使用document()和撒克遜擴展功能saxon:discard-document()的組合來加載和放棄文檔。

下面是我之前用於測試的一個示例。

XML文件列表(輸入到XSLT):

<files> 
    <file>file:///C:/input_xml/file1.xml</file> 
    <file>file:///C:/input_xml/file2.xml</file> 
    <file>file:///C:/input_xml/file3.xml</file> 
    <file>file:///C:/input_xml/file4.xml</file> 
    <file>file:///C:/input_xml/file5.xml</file> 
    <file>file:///C:/input_xml/file6.xml</file> 
    <file>file:///C:/input_xml/file7.xml</file> 
    <file>file:///C:/input_xml/file8.xml</file> 
    <file>file:///C:/input_xml/file9.xml</file> 
    <file>file:///C:/input_xml/file10.xml</file> 
</files> 

XSLT 2.0(與撒克遜9測試):

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:param name="pOutputDir" select="'output'"/> 

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

    <xsl:template match="files"> 
    <xsl:apply-templates/>  
    </xsl:template> 

    <xsl:template match="file"> 
    <xsl:variable name="vOutFile" select="tokenize(document-uri(document(.)),'/')[last()]"/> 
    <xsl:result-document href="{concat($pOutputDir,$vOutFile)}"> 
     <xsl:apply-templates select="document(.)/saxon:discard-document(.)" xmlns:saxon="http://saxon.sf.net/"/>   
    </xsl:result-document> 
    </xsl:template> 

</xsl:stylesheet> 

注:

再次,這個樣式表只是在做一個身份轉換。它通過不變的方式傳遞XML。您需要通過添加新模板來執行檢查/更改來覆蓋身份模板。

另請注意,輸出文件夾名稱只有一個參數。