2

国に基づいた固定の名前付けスキーマを持つ XML ファイルがたくさんあります: report_en.xmlreport_de.xml、など。XPath 関数を介してこれらの各ファイルを読み取り、いくつかの値を抽出して 1 つの XML ファイルを生成report_fr.xmlする XSLT スタイル シートを作成したいと考えています。document()要約付き。私の質問は次のとおりです。処理するファイルの正確な名前を知らなくても、ソース ファイルを反復処理するにはどうすればよいですか?

現時点では、すべてのファイル名を保持する補助 XML ファイルを生成し、スタイルシートで補助 XML ファイルを使用して反復することを計画しています。ファイル リストは、小さな PHP または bash スクリプトで生成されます。より良い代替手段はありますか?

私はXProcを認識していますが、現時点ではそれに多くの時間を投資することはできません。誰かが XProc ソリューションを投稿できるかもしれません。ソリューションには、レポートを HTML としてダウンロードして整理するワークフロー ステップが含まれていることが望ましいです :)

XSLT プロセッサとして Saxon を使用するので、使用できる Saxon 固有の拡張機能があれば、それも問題ありません。

4

2 に答える 2

4

Saxon 9.x で実装されている標準の XPath 2.x collection()関数を使用できます。

report_Saxon の実装では、検索パターンを関数の string-Uri 引数で使用できるため、ディレクトリのパスの後に、 で始まり、他の 2 つの文字を持ち、 で終わる任意のファイル名のパターンを指定できる場合があります.xml

この XPath 式:

collection('file:///c:/?select=report_*.xml')

で始まり、0 個以上の文字を持ち、. で終わるc:\名前のファイルに存在するすべての XML ドキュメントのドキュメント ノードを選択します。report_.xml

于 2010-06-01T16:51:12.343 に答える
2

Dimitre による答えは、あなたの場合の最も速い解決策のようです。しかし、あなたが尋ねたので、ここにXProcの代替案があります:

<p:declare-step version="1.0" xmlns:p="http://www.w3.org/ns/xproc" xmlns:c="http://www.w3.org/ns/xproc-step" exclude-inline-prefixes="#all" name="main">

<!-- create context for p:variable with base-uri pointing to the location of this file -->
<p:input port="source"><p:inline><x/></p:inline></p:input>

<!-- any params passed in from outside get passed through to p:xslt automatically! -->
<p:input port="parameters" kind="parameter"/>

<!-- configuration options for steering input and output -->
<p:option name="input-dir" select="'./'"/>
<p:option name="input-filter" select="'^report_.*\.xml$'"/>
<p:option name="output-dir" select="'./'"/>

<!-- resolve any path to base uri of this file, to make sure they are absolute -->
<p:variable name="abs-input-dir" select="resolve-uri($input-dir, base-uri(/))"/>
<p:variable name="abs-output-dir" select="resolve-uri($output-dir, base-uri(/))"/>

<!-- first step: get list of all files in input-dir -->
<p:directory-list>
    <p:with-option name="path" select="$abs-input-dir"/>
</p:directory-list>

<!-- iterate over each file to load it -->
<p:for-each>
    <p:iteration-source select="//c:file[matches(@name, $input-filter)]"/>
    <p:load>
        <p:with-option name="href" select="resolve-uri(/c:file/@name, $abs-input-dir)"/>
    </p:load>
</p:for-each>

<!-- wrap all files in a reports element to be able to hand it in to the xslt as a single input document -->
<p:wrap-sequence wrapper="reports"/>

<!-- apply the xslt (stylesheet is loaded below) -->
<p:xslt>
    <p:input port="stylesheet">
        <p:pipe step="style" port="result"/>
    </p:input>
</p:xslt>

<!-- store the result in the output dir -->
<p:store>
    <p:with-option name="href" select="resolve-uri('merged-reports.xml', $abs-output-dir)"/>
</p:store>

<!-- loading of the stylesheet.. -->
<p:load href="process-reports.xsl" name="style"/>

</p:declare-step>

たとえば、上記を process-reports.xpl として保存します。XMLCalabash (http://xmlcalabash.com/download/) で実行できます。次のように実行できます。

java -jar calabash.jar process-reports.xpl input-dir=./ output-dir=./

上記のコードは、すべてのレポートをラップする 1 つのドキュメントを取得し、それに対して少し処理を行う process-reports.xsl を想定しています。純粋な XProc で処理を行うこともできますが、この方法を好むかもしれません。

p:xslt ステップを p:for-each 内 (p:load の下) に移動することもできます。これにより、xslt が各レポートに個別に適用されます。

幸運を!

于 2011-11-11T07:42:40.087 に答える