2

中間 XML ファイルを使用していくつかの XSLT 変換を行う必要があります。(ファイルが必要です。実際のケースは、後のステップで中間ファイルをロードするため、もう少し注意が必要です)

first.xml ------------>   intermediate.xml ------------> final.xml
          first.xsl                         final.xsl

XProc パイプラインを作成したいと思います。次のコードを記述しようとしましたが、これによりエラーが発生します。

SCHWERWIEGEND: runxslt.xpl:26:44:err:XD0011:Could not read: intermediate.xml 
17.05.2012 15:15:35 com.xmlcalabash.drivers.Main error
SCHWERWIEGEND: It is a dynamic error if the resource referenced by a p:document element does not exist, cannot be accessed, or is not a well-formed XML document.
17.05.2012 15:15:35 com.xmlcalabash.drivers.Main error
SCHWERWIEGEND: Underlying exception: net.sf.saxon.s9api.SaxonApiException: I/O error reported by XML parser processing file:/<somepath>/intermediate.xml:
/<somepath>/intermediate.xml (No such file or directory)

(SCHWERWIEGEND は FATAL のようなものを意味します) したがって、明らかにファイルintermediate.xmlは書き込まれていません。

これはxpl私が使用したドキュメントです:

<?xml version="1.0" encoding="UTF-8"?>
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
  xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0">

  <p:input port="source">
    <p:document href="first.xml"/>
  </p:input>

  <p:output port="result" sequence="true">
    <p:empty/>
  </p:output>

  <p:xslt name="first-to-intermediate">
    <p:input port="stylesheet">
      <p:document href="first.xsl"/>
    </p:input>
    <p:input port="parameters">
      <p:empty/>
    </p:input>
  </p:xslt>

  <p:store href="intermediate.xml" />

  <p:xslt>
    <p:input port="source">
      <p:document href="intermediate.xml"/>
    </p:input>
    <p:input port="stylesheet">
      <p:document href="final.xsl"/>
    </p:input>
    <p:input port="parameters">
      <p:empty/>
    </p:input>
  </p:xslt>

  <p:store href="final.xml"/>

</p:declare-step>

完全を期すために、これらは変換ファイルです。

ソース.xml:

<root>
  <element name="A" />
</root>

最初の.xsl:

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

  <xsl:template match="root">
    <root>
      <xsl:apply-templates/>
    </root>
  </xsl:template>
  <xsl:template match="element">
    <intermediate name="A" />
  </xsl:template>

</xsl:stylesheet>

final.xsl:

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

  <xsl:template match="root">
    <root>
      <xsl:apply-templates/>
    </root>
  </xsl:template>
  <xsl:template match="intermediate">
    <final name="A" />
  </xsl:template>

</xsl:stylesheet>

実際のアプリケーションに関する注意事項を次に示します (上記はもちろん簡略化したものです)。

  1. 最初のステップ: ソースを処理に適したものに変換します。出力:companies.xml
  2. 手順 1 の出力を取得し、そこからインデックス ファイル ( index.xml) を作成します。インデックス ファイルは手動で編集できる必要があります。
  3. 3 番目のステップは、ステップ 1 と 2 で作成されたファイルをマージし、最終的な xml ( final.xml)を作成することです。

インデックス ファイルはディスクに書き込まれる必要があり、最後のステップを単独で実行できる必要があります (これは別の問題です。別のパイプラインを作成します)。

(ステップ 1)の出力companies.xmlはオプションであり、メモリに保存できます (ただし、大きくなる可能性があります)。

4

1 に答える 1

2

ここで XMLCalabash が機能しない理由がよくわかりません。ロジックは原則として機能するはずだと思いましたが、XMLCalabash はファイルのディスクへの書き込みを後で、おそらく最後まで保留しているようです。理由がわからない。

しかし、処理を続行する前に中間結果を保存する必要がないため、洗練された解決策があります。実際、ハードコーディングされたロードとストアをまったく使用しないことが最善です。代わりに、次のようなものを使用します。

<?xml version="1.0" encoding="UTF-8"?> 
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" 
  xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0"> 

  <p:input port="source" sequence="true"/> 
  <p:input port="parameters" kind="parameter"/>
  <p:output port="result" sequence="true"/> 

  <p:xslt name="first-to-intermediate"> 
    <p:input port="stylesheet"> 
      <p:document href="first.xsl"/> 
    </p:input> 
  </p:xslt> 

  <p:xslt> 
    <p:input port="stylesheet"> 
      <p:document href="final.xsl"/> 
    </p:input> 
  </p:xslt> 

</p:declare-step> 

XMLCalabash へのわずかに異なる呼び出しが必要です。次のように呼び出します。

java -jar Calabash.jar -i source=first.xml -o result=final.xml runxslt.xpl

-i を使用すると、入力ソースを入力ファイルに関連付けることができますが、スクリプトの外部から実行されるため、ハードコーディングは必要ありません。同様に -o を使用すると、出力をターゲット ファイルにリダイレクトします。

また、コードに「パラメーター」入力を追加しました。これは、p:xslt のパラメーターに自動的に接続されます。そうすれば、ap:empty でそれらを指定する必要はありません。また、コマンドラインからこれらの xslt にパラメーター値を渡すこともできます。

また、p:store を削除したため、2 番目の p:xslt の「ソース」入力も必要ありません。最初の p:xslt の結果は、デフォルトで次のステップの (プライマリ) ソース入力に直接入ります。

- 編集 -

ディスクから中間​​ドキュメントをロードせずに、最初の p:xslt の出力をap:storeして再利用できるという私自身のコメントを詳しく説明します。次のように実行できます。

<?xml version="1.0" encoding="UTF-8"?> 
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" 
  xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0"> 

  <p:input port="source" sequence="false"/> 
  <p:input port="parameters" kind="parameter"/>
  <p:output port="result" sequence="false"/> 

  <p:xslt name="first-to-intermediate"> 
    <p:input port="stylesheet"> 
      <p:document href="first.xsl"/> 
    </p:input> 
  </p:xslt> 

  <p:store href="intermediate.xml"/>

  <p:xslt> 
    <p:input port="source"> 
      <p:pipe step="first-to-intermediate" port="result"/> 
    </p:input> 
    <p:input port="stylesheet"> 
      <p:document href="final.xsl"/> 
    </p:input> 
  </p:xslt> 

</p:declare-step> 

宣言ステップの入力と出力の両方で、sequence=true を false に変更したことに注意してください。中間結果のシーケンスを保存するには、特別な注意が必要です。これで間違いは防げるはずです。

チッ!

于 2012-05-17T18:13:14.410 に答える