XdsCmd_V50 コマンド

XdsCmd_V50 はクライアント側のプログラムで、次の一連の処理を行うコマンドラインインターフェイスのプログラムです。 ウェブサービスを利用する各クライアントマシンにインストールする必要があります。

  1. コマンドファイルを読み、ウェブサーバへのリクエストを行います。
  2. ウェブサーバから返ってきた結果をコマンドファイルで指定されたファイルに格納します。

コマンドファイルは XdsCmd_V50 のための XML形式のファイルで、次のような内容が含まれています。

XdsCmd_V50 コマンドは次のように起動します。 パラメータのコマンドファイルを省略することはできません。

> XdsCmd_V50 Command-File

これにより、XdsCmd_V50 はコマンドファイルの内容をサーバに伝え、サーバからの結果を指定されたファイルに格納します。

XdsCmd_V50 コマンド実行時に、次のように -v パラメータを付けることができます。

> XdsCmd_V50 -v Command-File

このとき、コンソールには実行経過がレポートされます。

ウェブサーバへのリクエストで次のようなメッセージが表示されたときは、ユーザ認証に失敗しています。 <session>要素を使用して正しいユーザ名を指定してください。

SOAP FAULT: SOAP-ENV:Server
"HTTP error"
Detail: HTTP/1.1 401 Unauthorized

Fault Code: [], Fault Reason: [], Fault Detail: [HTTP/1.1 401 Unauthorized]

コマンドファイルの例

次は、製品に添付されているサンプルです。このコマンドファイルは次のような内容です。

<?xml version="1.0"?>
<command target="http://localhost:8088/axds/">
 <request>
  <script>
try {
  var xml = ContentsManager.getContent("xmlsrc");
  var xsl = ContentsManager.getContent("xslsrc");
  var transformer = new Transformer("xslt");
  if (transformer == null) {
    throw ("Can't create transformer.");
  }
  var fo = transformer.transform(xml, xsl, "text/xml");
  var renderer = new Renderer("pdf", "fo6");
  if (renderer == null) {
    throw ("Can't create renderer.");
  }
  renderer.measuretime = true;
  var pdf = renderer.render(fo);
  var resulttime = new ContentStream();
  resulttime.putData(renderer.elapsetime + "m sec");
  Response.put("resultfo", fo);
  Response.put("resultpdf", pdf);
  Response.put("resulttime", resulttime);
} catch(_error) {
  Response.setFault(Fault.FAULT_CODE_SENDER, _error);
}
  </script>
  <data name="xmlsrc" src="NumberFormatTest.xml"/>
  <data name="xslsrc" src="NumberFormatTest.xsl"/>
  <data src="img/antenaLogo.jpg"/>
  <data src="img/ico4.png"/>
  <data src="img/sakura.jpg"/>
 </request>
 <response>
  <result name="resultfo" dst="result/NumberFormatTest.fo"/>
  <result name="resultpdf" dst="result/NumberFormatTest.pdf"/>
  <result name="resulttime" dst="result/elapse-time.txt"/>
 </response>
</command>

このコマンドファイルの内容を解説します。

このコマンドファイルは、カレントディレクトリにある NumberFormatTest.xmlNumberFormatTest.xsl というふたつのファイルをサーバへ送り、結果を result というフォルダの下に3つ返します。

<command>要素は、コマンド全体を表すルート要素です。 ここで接続先のウェブサーバを指定します。ここでは、http://localhost:8088/axds/ を指定しています。これは、実際に起動されている接続可能なサーバと一致している必要があります。 <command>要素の子要素には、<request>要素<response>要素があります。 <request>要素ではウェブサーバへのリクエストを記述し、<response>要素ではウェブサーバからのレスポンスの格納方法を記述します。

<request>要素には、ウェブサーバで実行する処理を記述した<script>要素と、ウェブサーバに送るデータを記述した<data>要素があります。 <script>要素の内容はJavaScriptです。

ここでは、<data>要素がふたつ含まれています。それぞれサーバへ送出するクライアント上のファイルを指定します。ひとつは、NumberFormatTest.xml というファイルで、xmlsrc という名前が付けられています。

<data name="xmlsrc" src="NumberFormatTest.xml"/>

もうひとつは、NumberFormatTest.xsl というファイルで、xslsrc という名前が付けられています。

<data name="xslsrc" src="NumberFormatTest.xsl"/>

この名前はJavaScript中で参照され、送られてきたファイルを識別するために利用されます。 それぞれのファイルには別々の名前を付けなければなりません。

同様に、サーバから送られて来るデータを受け取るために、<response>要素内に<result>要素で保存先ファイル名とその名前を指定しておきます。

<result name="resultfo" dst="result/NumberFormatTest.fo"/>
<result name="resultpdf" dst="result/NumberFormatTest.pdf"/>
<result name="resulttime" dst="result/elapse-time.txt"/>

<data>要素と<result>要素で指定する名前には任意のものを付けることができますが、コマンドファイル中で一意でなければなりません。

<script>要素内のJavaScriptを見てみましょう。 プログラムは、

try {
  ...
} catch () {
  ...
}

で囲まれています。 サーバでの処理途中でエラーが起こると例外が発生します。コマンドファイル内のJavaScriptは、必ずこのような構造で書くようにします。

最初にある、

var xml = ContentsManager.getContent("xmlsrc");
var xsl = ContentsManager.getContent("xslsrc");

という記述は、クライアントから送られてきたデータを表しています。ContentsManagerオブジェクトがそのデータを管理しています。 <data>要素で指定した名前を使ってそのデータを取り出すことができます。 ここでは、XML文書とXSLスタイルシートを受け取っています。

次に

var transformer = new Transformer("xslt");

で、XSLT変換用のTransformerオブジェクトを生成し、

var fo = transformer.transform(xml, xsl, "text/xml");

で、XSLT変換を実行しXSL-FOを得ます。 ここにある "xslt""text/xml" といった文字列には、決められたものが指定できます。詳細は、JavaScriptを参照してください。

そして、

var renderer = new Renderer("pdf", "fo6");

で、描画用のRendererオブジェクトを生成します。

このとき、ふたつめのパラメータに、使用する AH Formatter の種別を指定します。組み合わせには AH Formatter V6 を使用するため"fo6"を指定してください。何も指定がない場合は、"fo6"を指定したのと同じになります。

そして、

var pdf = renderer.render(fo);

で、XSL-FOを描画してPDFを生成しています。 この結果をクライアントに戻すためには、

Response.put("resultfo", fo);
Response.put("resultpdf", pdf);

のように、Responseオブジェクトで行います。 ここで、<result>要素で指定されている名前を使用します。もし、<result>要素に対応する名前が見つからなかった場合は、その名前そのものが結果のファイル名とみなされます。つまり、

Response.put("NumberFormatTest.pdf", pdf);
 ...
<result dst="NumberFormatTest.pdf"/>

のように、name属性がない<result>要素は記述する必要がありません。

途中、ContentStreamオブジェクトを使って経過時間を計りクライアントに通知しています。これは付加的な情報で、PDF生成とは関係ありません。

ContentsManagerとURIの解決

FO中で画像を参照しているとします。その参照方法には何通りか方法があります。

http: を使う場合はサーバからそのリソースが参照可能でなければなりませんが、 data: で指定されている場合は問題ありません。 file: で指定されている場合、そのファイルはサーバ上のファイルを参照します。 これらはいずれもサーバから参照できるリソースのため、クライアントからサーバへリソースを送信する必要はありません。 一方、相対パスで指定されているリソースはすべてサーバへ送信してやる必要があります。 それは、<data>要素で指定します。

ここでは、サーバ上のContentsManagerがクライアントから送信されたリソースと、FO中などに書かれている相対URIの対応付けをどのように行うのかを解説します。

次は、製品に添付されている簡単なサンプルです。

<?xml version="1.0"?>
<command target="http://localhost:8088/axds/">
<request>
<script>
try {
  var fo = ContentsManager.getContent("hello.fo");
  var renderer = new Renderer("pdf", "fo6");
  if (renderer == null) {
    throw ("Can't create renderer.");
  }
  var pdf = renderer.render(fo);
  Response.put("hello.pdf", pdf);
} catch(_error) {
  Response.setFault(Fault.FAULT_CODE_RECEIVER, _error);
}
</script>
<data src="hello.fo"/>
<data src="img/ahlogo.svg"/>
</request>
</command>

<data>要素のsrc属性にはクライアントのコマンドファイルから参照可能な相対アドレスが記入されます。XdsCmd_V50 は、そのファイルをサーバへ送信します。 サーバは、受け取ったファイルを <data>要素のname属性の値を識別子として使ってContentsManagerで管理します。 上の例ではname属性は省略されているので、src属性の値を識別子とします。img/ahlogo.svg です

FO中には、

<fo:external-graphic src="img/ahlogo.svg"/>

と書かれています。 サーバは、このURI img/ahlogo.svg を識別子としてContentsManagerからリソースを取得します。 このときのクライアントは次のようなディレクトリ構造です。

.-+- command.xml
  +- hello.fo
  +- img/
      +- ahlogo.svg

次に、クライアントが次のようなディレクトリ構造だとします。

.-+- command.xml
  +- fo/
  |   +- hello.fo
  +- img/
      +- ahlogo.svg

このとき、FO中には

<fo:external-graphic src="../img/ahlogo.svg"/>

と書かれています。 コマンドファイルには、

<data src="fo/hello.fo"/>
<data src="img/ahlogo.svg"/>

と指定します。 JavaScriptでのFOの取得は ContentsManager.getContent("fo/hello.fo") となります。

ContentsManagerは、getContent() に指定された名前を使って内部的に仮想URIを作ってリソースを管理しています。それは、

http://localhost:8080/axds/session-id/fo/hello.fo

というようなものです(session-id は、システムが各セッションに対して振るユニークな番号です)。 このURIを使ってFO中の相対URIを解決します。 つまり、FO中に src="../img/ahlogo.svg" と書かれていれば、そのリソースはContentsManagerに対して

http://localhost:8080/axds/session-id/img/ahlogo.svg

となり、<data src="img/ahlogo.svg"/> の指定と一致します。

もし、

<data src="fo/hello.fo" name="hello.fo"/>

とした場合、そのFOはContentsManagerに対して

http://localhost:8080/axds/session-id/hello.fo

と管理されることになり、FO中のsrc="../img/ahlogo.svg" は、

http://localhost:8080/axds/img/ahlogo.svg

となって、<data src="img/ahlogo.svg"/> の指定と一致しません。

次に、クライアントが次のようなディレクトリ構造だとします。

.-+- command.xml
  +- data/
      +- hello.fo
      +- ahlogo.svg

このとき、FO中には

<fo:external-graphic src="ahlogo.svg"/>

と書かれています。 コマンドファイルには、

<data src="data/hello.fo" name="hello.fo"/>
<data src="data/ahlogo.svg" name="ahlogo.svg"/>

と指定することができます。

XMLとXSLスタイルシートを指定するような場合、XMLは、command.xml と同じ位置に置くようにしてください。 使用するXMLパーサによって、XML中で参照する実体定義などがサーバ上で利用できないことがあります。

コマンドファイルの要素

<command>

コマンドファイルのルート要素です。

Contents: (request, response?)
Attributes: target : ウェブサービスを提供するサービスポイントのURIを指定します。
src : セッションを利用するときにXMLファイルのURIを指定できます。このXMLファイルには<command>要素を記述できます。このとき、自身の<command>要素が内容を持っていても無視されます。
connect-timeout : サーバへ接続するときのタイムアウト値を秒で指定します。
send-timeout : サーバへリクエストを送信するときのタイムアウト値を秒で指定します。
receive-timeout : サーバからレスポンスを受信するときのタイムアウト値を秒で指定します。

タイムアウトの既定値は 0 です。0 のときはタイムアウトしません。

<request>

ウェブサーバへのリクエスト内容を指定します。

Contents: (script, data*)
Attributes: なし

<script>

ウェブサーバで実行するスクリプトを指定します。 内容のテキストにJavaScriptを直接記述するか、src属性でJavaScriptのスクリプトファイルを指定します。 両方を指定した場合はsrc属性が優先され、内容のテキストは無視されます。

Contents: #PCDATA
Attributes: src : JavaScriptを格納したファイルのURIを指定します。相対指定の場合はコマンドファイルのあるディレクトリからの相対となります。

ここで指定されたJavaScriptは、ウェブサーバへ送られます。ウェブサーバはその記述に従ってさまざまな処理を行い、結果をクライアント側へ返します。JavaScriptの書き方については、「JavaScript」を参照してください。

<data>

ウェブサーバへ送るデータを指定します。 内容のテキストにデータを直接記述するか、src属性でデータファイルを指定します。 両方を指定した場合はsrc属性が優先され、内容のテキストは無視されます。

Contents: #PCDATA
Attributes: name : データに付ける名前を指定します。src属性を指定した場合は省略可能で、そのときはsrc属性の値がデータの名前となります。
src : データを格納してあるファイルのURIを指定します。相対指定の場合はコマンドファイルのあるディレクトリからの相対となります。

ここで指定されたデータは、名前を伴ってウェブサーバへ送られます。送られたデータは、JavaScript中で参照され処理されます。

注意: クライアントから送るべきリソースは、すべて <data> に列挙しなければなりません。もしそこに不足があった場合、サーバ側ではそれを検知できず、単に空の内容となって処理が続行されてしまいます。

<response>

ウェブサーバから戻ってきた結果のデータの格納方法を指定します。

Contents: (result*)
Attributes: name-template : 処理結果を格納する際のファイル名のテンプレートを指定します。これは、<result>要素で指定されなかったデータに対して有効になります。 テンプレート中に $NAME$SEQ を指定することができ、それぞれデータ名とレスポンス内でのシーケンス番号に置き換えられます。 相対指定の場合はコマンドファイルのあるディレクトリからの相対となります。既定値は、$NAME です。 $ 自身を表現することはできません。

<response>要素が指定されなかったり、name-template属性が空だった場合は、JavaScript中のResponseオブジェクトで指定された処理結果のデータ名が格納先のファイル名となります。

<result>

各結果のデータの格納方法を表します。

Contents: EMPTY
Attributes: name : レスポンス内の結果データの名前を指定します。
dst : 結果を格納するファイル名を指定します。相対指定の場合はコマンドファイルのあるディレクトリからの相対となります。

name属性がない<result>要素は、記述する必要がありません。 JavaScript中のResponseオブジェクトで、対応する<result>要素がないときは、指定された処理結果のデータ名が格納先のファイル名となります。

セッションの利用

コマンドファイルでセッションを利用したサンプルを以下に示します。この例では、XSLT変換と描画とを別のコマンドとして実行しています。ふたつ目のコマンドで描画を行っていますが、XSLT変換で作成したFOは JavaScriptのContentsManagerオブジェクトから取得し、FOで参照する外部の画像ファイルはデータとして送り込んでいます。

<?xml version="1.0"?>
<session target="http://localhost:8088/" userid="guest" passwd="">
<command>
 <request>
  <script>
try {
  var xml = ContentsManager.getContent("module.xml");
  var xsl = ContentsManager.getContent("module-To-FO.xsl");
  var transformer = new Transformer("xslt");
  if (transformer == null) {
    throw ("Can't create transformer.");
  }
  var fo = transformer.transform(xml, xsl, "text/xml");
  ContentsManager.addContent("module.fo", fo);
  Response.put("resultfo", fo);
} catch(_error) {
  Response.setFault(Fault.FAULT_CODE_RECEIVER, _error);
}
  </script>
  <data name="module.xml" src="module.xml"/>
  <data name="module-To-FO.xsl" src="module-To-FO.xsl"/>
 </request>
 <response>
  <result name="resultfo" dst="result/module.fo"/>
 </response>
</command>

<command>
 <request>
  <script>
try {
  var fo = ContentsManager.getContent("module.fo");
  var renderer = new Renderer("pdf", "fo6");
  if (renderer == null) {
    throw ("Can't create renderer.");
  }
  var pdf = renderer.render(fo);
  Response.put("resultpdf", pdf);
  var vers = new ContentStream;
  vers.putData(renderer.version);
  Response.put("xslfover", vers);
} catch(_error) {
  Response.setFault(Fault.FAULT_CODE_RECEIVER, _error);
}
  </script>
  
  <data src="images/logo.bmp"/>
  <data src="images/fig1-1.jpg"/>
  <data src="images/fig1-2.png"/>
 </request>
 <response>
  <result name="resultpdf" dst="result/SampleCompany.pdf"/>
  <result name="resulttime" dst="result/elapse-time.txt"/>
 </response>
</command>
</session>

<session>要素の子要素となる<command>要素では、外部のファイルから<command>要素を取り込むことができます。<command>要素のsrc属性で外部ファイルのURIを指定することで、<command>要素の内容を取り込みます。内容のテキストとsrc属性の両方を指定した場合は、src属性が優先されて内容のテキストは無視されます。上記の例では、ふたつの<command>要素がそれぞれ command1.xmlcommand2.xml というファイルにある場合、次のように書くことができます。

<?xml version="1.0"?>
<session target="http://localhost:8088/" userid="guest" passwd="">
<command src="command1.xml"/>
<command src="command2.xml"/>
</session>

ここに command1.xml は次のような内容です。command2.xml も同様な<command>要素からなるXMLです。

<?xml version="1.0"?>
<command>
 <request>
  <script>
try {
  var xml = ContentsManager.getContent("module.xml");
  var xsl = ContentsManager.getContent("module-To-FO.xsl");
  var transformer = new Transformer("xslt");
  if (transformer == null) {
    throw ("Can't create transformer.");
  }
  var fo = transformer.transform(xml, xsl, "text/xml");
  ContentsManager.addContent("module.fo", fo);
  Response.put("resultfo", fo);
} catch(_error) {
  Response.setFault(Fault.FAULT_CODE_RECEIVER, _error);
}
  </script>
  <data name="module.xml" src="module.xml"/>
  <data name="module-To-FO.xsl" src="module-To-FO.xsl"/>
 </request>
 <response>
  <result name="resultfo" dst="result/module.fo"/>
 </response>
</command>

<command>要素のsrc属性で取り込んだ<command>要素がtarget属性やsrc属性を持っていても、それらの属性は無視されます。

<session>

<session>要素は、セッションを利用する場合のコマンドファイルのルート要素です。

Contents: (command+)
Attributes: target : ウェブサービスを提供するエンドポイントのURIを指定します。
userid : セッションをオープンする際のユーザIDを指定します。
passwd : ユーザのパスワードを指定します。

ユーザIDは必ず指定しなければなりません。 ユーザIDはサーバの設定ファイルで管理されています。

コマンドファイルを使ったサンプル

含まれているサンプルのコマンドファイルは、ウェブサービスのエントリポイントに target="http://localhost:8088/axds/" が指定されています。 実際に動作させるときは、それぞれのサンプルに添付されている readme.txt をお読みになり、実際の動作環境に合わせて修正してください。

  1. このサンプルは、FOをPDFに変換して返す、もっとも簡単なサンプルです。

    command.xml
  2. このサンプルは、画像を利用しているXML文書をXSLスタイルシートを用いてFOに変換し、そのFOをPDFに変換します。そして、FOとPDFをクライアントに返します。そのとき、result/ というディレクトリを作って、その下にFOとPDFを保存します。

    command.xml
  3. このサンプルは、FOから参照される画像ファイルは、ウェブサーバ上にあるファイルを利用するようにしています。XML中では、相対パスで指定されているそれらの画像をウェブサーバ上のものを参照するように処理しています。つまり、クライアントからそれらの画像を送信していません。 画像は、ウェブサーバの C:/AXDS/samples/sample-03/img/ フォルダの下に存在するものと仮定しています。実際に試されるときは、sample-03/img/ をサーバにコピーし、command.xml 中のそのアドレスを修正してください。

    command.xml
  4. このサンプルは、XML文書をXSLスタイルシートを用いてFOに変換し、そのFOをPDFに変換します。 FOへの変換の際、XSLTプロセッサのパラメータ設定で用紙の大きさを変えてふたつのFOを生成し、それぞれをPDFに変換します。そのとき、PDFへの変換時に埋め込む画像を変えています。

    command.xml
  5. このサンプルは、XML文書をXSLスタイルシートを用いてFOに変換し、そのFOをPDFに変換します。 PDFを作成する際、PDFオプションでパスワードを設定したPDFとパスワードを設定しないPDFのふたつのPDFを作成します。

    command.xml
  6. このサンプルは、XML文書をXSLスタイルシートを用いてFOに変換し、そのFOをPDFに変換します。 そのとき、PDF作成にかかる時間を測定して結果を返します。

    command.xml
  7. このサンプルは、セッションを確立してFOへの変換とFOからPDFへの変換を別のコマンドで処理しています。 session.xml ではセッションをオープンし、中で command1.xmlcommand2.xml を参照しています。command1.xml は、XMLファイルとXSLスタイルシートからFOを作成して返します。command2.xml は、前のコマンドで作成したFOと、クライアントから送られた画像ファイルを使ってPDFを作成して返します。

    session.xml, command1.xml, command2.xml
  8. このサンプルは、AH Formatter を使用し、HTML文書をPDFに変換します。PDFへの変換時にHTML文書内に記述されたスタイル定義を参照します。

    command.xml
  9. このサンプルは、AH Formatter を使用し、HTML文書とCSSスタイルシートを用いてPDFに変換します。

    command.xml
  10. このサンプルは、AH Formatter を使用し、XML文書とCSSスタイルシートを用いてPDFに変換します。XML文書を読み込む際に組版種別にXML+CSSを指定しています。組版種別を指定しない場合は、AH Formatter 側で自動的に文書の種類が判断されて処理されます。

    command.xml


Copyright © 2005-2016 Antenna House, Inc. All rights reserved.
Antenna House is a trademark of Antenna House, Inc.