XSL Formatter V2 Q&A

XSLT/XSL-FO 仕様について

XSLT

XSL-FO

トップ
基本・一般
XSL Formatter について
操作方法
プログラミング
XSLT/XSL-FO 仕様について
XSLT/XSL-FO テクニック
索引

XSLT

Q.  既存のXML文書とXSLを利用し、XSL Formatter で組版実行を行いました。ところが、XSLの方に記述した、 <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> が、エラーになりました。これはなぜなのでしょう。 [No.2002011521]
A. 

XSL Formatter は、XSLT V1.0勧告のスタイルシートでなければと受け付けません。このエラーは直接的には、スタイルシートが古いドラフト仕様のものであることを示しています。スタイルシートを XSLT V1.0勧告に準拠するように変更してください。 しかし、既存のXSLを利用されているということですので、スタイルシートの内容がHTMLに変換するものではないかと思われます。したがって、さらに、スタイルシートの内容を、XSL-FOを出力するように根本的に変更する必要があります。こちら にチュートリアルを用意しましたので、ご参照ください。


Q.  XSLTスタイルシート内で、正規表現を使用することは可能ですか。 [No.2003040402]
A. 

XSLTとXPathの仕様では正規表現が使えません。 したがって、通常の状態では正規表現を使った文字列操作は不可能です。
しかし、XSLTを拡張することができます。 これは、XSLTプロセッサに依存しますが、XSL Formatterでは、XSLTプロセッサを選択できるので、問題は解決できるでしょう。
ひとつは、XSLTスタイルシートでJavaScriptを使うことです。 JavaScriptで正規表現を使って文字列操作が可能です。 使い方は、使用しているXSLTプロセッサの仕様を調べてください。
他に、JavaScript以外にもXSLTプロセッサによる拡張が実装されている場合がありますので、ご使用のXSLTプロセッサの仕様を調べてください。


Q.  <?xml-stylesheet href="xxx.css" type="text/css"?> という指定をした場合、このCSSは認識されますか。 [No.2003111701]
A. 

XSL Formatter は、XSL-FOを対象としますので、CSSは認識しません。
XMLファイル中にCSSファイル名を記述して、GUI もしくはコマンドラインにてスタイルシートの指定が無い場合はエラーになります。
スタイルシートを指定してXSL-FOに変換された場合はエラーにならず、CSSの指定は無視されます。


XSL-FO

Q.  XSL Formatter は glyph-orientation-vertical はサポートしていますか。 [No.2002030102]
A. 

いいえ。現状では glyph-orientation-vertical はサポートしておりません。ご了承ください。


Q.  「Invalid property value:border-before-width="1"」というエラーメッセージが出てしまいます。なぜですか。 [No.2002041205]
A. 

プロパテイ値に単位がついていないとエラーになってしまいます。必ず単位を指定するようにしてください。


Q.  ページの始めのblockで space-before="2.0in" を指定したのですが、有効になりません。なぜですか。 [No.2002102507]
A. 

例えば次のFOのとき、space-before="2.0in" は有効になりません。

<fo:flow>
<fo:block space-before="2.0in">
    AAAAAAAA
</fo:block>
</fo:flow>

参照エリア、行エリアの先頭と最後のspaceの conditionality は "discard" がデフォルトです。 したがって、参照エリアの始めの block で space-before="2.0in"を指定しても、space-before.conditionality="discard" によって無効になります。

また、次の例でも同じです。

<fo:flow>
<fo:block>
<fo:block space-before="2.0in">
    AAAAAAAA
</fo:block>
</fo:block>
</fo:flow>

親のblockに discard の対象となる space や border/padding がない場合、子の最初のblockに条件が当てはまり、space-before.conditionality="discard"となるので、子のblockに設定されているspace-before="2.0in"は無効になります。

よって、space-beforeを有効にしたいときは、次のようにspace conditionalityを"retain"にする必要があります。

<fo:flow>
<fo:block space-before="2.0in" space-before.conditionality="retain">
    AAAAAAAA
</fo:block>
</fo:flow>

Q.  同じ親要素で、同じ"marker-class-name" の値を持っているfo:markerを2以上指定してFOを組版しても、XSL Formatterはエラーメッセージを表示しません。 これはXSL仕様書の「6.11.3, Constraints: no duplicate marker class names w/in same parent」に従ってないのではありませんか。 [No.2002111507]
A. 

これはXSL-FOの仕様に従っていないわけではありません。単にエラーチェックを省略しているだけです。XSL-FO仕様で、エラーメッセージを発生させるということは義務ではないです。


Q.  orphans/widowsプロパティを指定したのですが、有効になりません。 [No.2003050901]
A. 

W3C XSL-FO仕様から参照されているCSS2の仕様には次のように書かれています。(http://www.w3.org/TR/REC-CSS2/page.html#allowed-page-breaks を参照してください)

13.3.4 Allowed page breaks

In the normal flow, page breaks can occur at the following places:

1. In the vertical margin between block boxes. When a page break occurs
here, the computed values of the relevant 'margin-top' and 'margin-bottom'
properties are set to '0'.

2. Between line boxes inside a block box.

These breaks are subject to the following rules:

Rule A: Breaking at (1) is allowed only if the 'page-break-after' and 'pagebreak-
before' properties of all the elements generating boxes that meet at
this margin allow it, which is when at least one of them has the value
'always', 'left', or 'right', or when all of them are 'auto'.

Rule B: However, if all of them are 'auto' and the nearest common ancestor
of all the elements has a 'page-break-inside' value of 'avoid', then breaking
here is not allowed.

Rule C: Breaking at (2) is allowed only if the number of line boxes between
the break and the start of the enclosing block box is the value of 'orphans' or
more, and the number of line boxes between the break and the end of the
box is the value of 'widows' or more.

Rule D: In addition, breaking at (2) is allowed only if the 'page-break-inside'
property is 'auto'.

Rule Cがorphansやwidowsが適用される条件です。これは"2.Between line boxes inside a block box."の場合ですので、一つのblockの中のlineに対してorphans/widowsが適用されます。
したがって、orphans/widowsプロパティを指定したblock areaの中に複数のblockが含まれている場合、内側のblockの境界では改ページすることがあります。


Q.  <fo:page-number/> で、ページの設定をする際に、開始ページを 0 から始めることは可能ですか。 [No.2003111704]
A. 

page-sequence の開始ページを 0 から始めるのは不可能です。

7.25.7. "initial-page-number"

Values have the following meanings:
<integer>

A positive integer. If a negative or non-integer value is provided, the
value will be rounded to the nearest integer value greater than or equal
to 1.

したがって、0 を指定しても初期値は 1 になります。


Q.  fo:inlinewidthpadding-left を指定したところ、その fo:inline の幅は widthpadding-left になりました。Internet Explorer 6 と出力結果が異なります。 [No.2004040201]
A. 

width プロパティは content-rectangle の幅です。 border-widthpadding-left/padding-right は含まれません。

IE が CSS の仕様と異なっている件は CSS Enhancements in Internet Explorer 6 を参照してください。


Q.  side-float によって移動された fo:blocktext-indent が指定されているのですが有効になりません。 [No.2004040202]
A. 

これは intrusion-displace の正しい動作です。intrusion-displace が指定されていない場合(デフォルトの auto )は以下のように定義されています。

7.18.3. “intrusion-displace”
auto
For a reference-area, this value is treated as if "block" had been specified. For any other area, this
value is treated as if "line" had been specified.
....
block
The start edge (and end edge) of the block is displaced by the least amount necessary to insure
that (a) the start edge (end edge) of the block does not intersect any of the start intrusions (end
intrusions) that overlap that block and (b) the amount by which it is displaced is at least as much
as the displacement of the parent area, provided the parent is a block-area which is not a referencearea.
An intrusion is said to overlap a block if the there is a line parallel to the inline progression
direction that intersects the allocation rectangles of both the block and the intrusion.

block の start edge と end edge は必要最小量の位置で配置されます。つまり fo:block に指定された indent は (side-float によって移動された値よりも大きくない限り) 無効になります。

fo:block に指定した indent を有効にする場合は、intrusion-displace="indent" を指定してください。

indent
The start edge (and end edge) of each line within the block area on which the property occurs is
displaced (a) by at least the same amount it would be displaced by the "line" value of this property
and (b) in addition, by an amount that preserves the relative offset of that start edge (or end edge)
with respect to the start edge (or end edge) of any other line displaced by any intrusion that cause
the current line to be displaced. If there is more than one intrusion that could cause a displacement
of the line, the largest such displacement is used.

Q.  fo:table-cell 内の fo:block に指定したbreak-after="page" が有効になりません。なぜですか。 [No.2004042702]
A. 

FOは以下のようになっていました。

<fo:table-row >
<fo:table-cell >
<fo:block break-after="page">Cell 1</fo:block>
</fo:table-cell>
</fo:table-row>

XSL-FO仕様の 4.8 Keeps and Breaks では、以下のように break-after 条件が定義されています。

A break-after condition depends on the next formatting object in the flow; 
the condition is satisfied if either there is no such next formatting object, or 
if the first normal area generated and returned by that formatting object is 
leading in a context-area.

table-cell 内の最後の FO に指定された break-after="page" の条件を満たすには、flow 内でのその FO の次の FO が存在しないか、次の FO が生成するエリアがページの先頭になればいいということです。cell 内容はそれぞれ独立した flow であると考えられます。したがって、次の FO というのは存在しないので、この break-after 条件は満たされます。

もしこの条件を踏まえなかった場合、以下のようなFOで矛盾が発生することになります。

<fo:table-row >
<fo:table-cell >
<fo:block break-after="page">Cell 1</fo:block>
</fo:table-cell>
<fo:table-cell >
<fo:block >Cell 2</fo:block>
</fo:table-cell>
</fo:table-row>

Q.  ネストしたテーブルに width="100%" を指定したのですが、内側のテーブルの幅がセルいっぱいにならずに、右側にスペースがあります。 [No.2004050602]
A. 

FO は以下のようになっていました。

<fo:block margin-right="8.0px" margin-left="8.0px" ...>
  ...
  <fo:table margin-right="2.0px" margin-left="2.0px"
            border-left-width="2.0px" border-right-width="2.0px" ...
            width="100.0%">
    ...
      <fo:table-cell padding-left="1.0px" padding-right="1.0px" ...>
        <fo:block>
          ...
          <fo:table margin-right="0pt" margin-left="0pt"
                    border-left-width="2.0px" border-right-width="2.0px" ...
                    width="100.0%">
            ...
              <fo:table-cell padding-left="1.0px" padding-right="1.0px" ...>
                <fo:block>
                  <fo:table margin-right="0pt" margin-left="0pt"
                    border-left-width="2.0px" border-right-width="2.0px" ...
                    width="100.0%">
                    ...

ここで重要なのは、エリアの幅の%指定の基準は、そのエリアの親エリアの content-rectangle の幅であるということです。一番外側のテーブルの幅の width=100% は、テーブルを包含する block の content-rectangle の幅です。この block には margin-right="8.0px" margin-left="8.0px" が指定されているので、その分(16px)だけ region-body の幅よりも小さくなります。

2番目のテーブルも同様にその親の block の content-rectangle の幅になります。この block には継承されたインデントがあります。このインデントは外側のテーブルに指定されている margin-left/right(各々2px) と border-left/right(各々2px)の和です。XSL-FO仕様の "5.3.2 Margin, Space, and Indent Properties" を参照してください。したがって、この分(合計8px)が外側のセルの幅よりも小さくなります。

3番目のテーブルも2番目のテーブルも同様ですが、2番目のテーブルに指定されている margin-left/right が 0pt なので外側のセルの幅よりも小さくなる量は 2番目のテーブルの border-left/right の分(合計4px)だけとなります。


Copyright © 1999-2004 Antenna House, Inc. All rights reserved.
Antenna House is a trademark of Antenna House, Inc.