- PR -

表組について

投稿者投稿内容
tsuyoshi
会議室デビュー日: 2002/07/27
投稿数: 3
投稿日時: 2002-07-27 10:47
はじめましてtsuyoshiです。

早速、質問なのですが、こんな入力ソース(テキストデータは例です)をスタイルシート(XSLT1.0)で変換してこんな出力ソースにしたいのですが、できなくて(objectの白黒表示)よかったら教えてください。変数を利用したスタイルシートを作ってみたのでのせときます。
出力のルールは@とAだけです。


<入力ソース>
<page>
<object division="3">中央線</object>
<object division="1">新宿</object>
<object division="1">新宿</object>
<object division="1">新宿</object>
<object division="2">新宿は京王線をごらんください</object>
<object division="1">吉祥寺</object>
<object division="1">吉祥寺</object>
<object division="1">吉祥寺</object>
</page>
<page>
<object division="1">吉祥寺</object>
<object division="2">吉祥寺は井の頭線をごらんください</object>
<object division="1">八王子</object>
<object division="1">八王子</object>
<object division="3">京王線</object>
<object division="1">八王子</object>
<object division="1">八王子</object>
<object division="1">八王子</object>
</page>

<出力ソース>
中央線
白 ・・・・・・・・・・・・・・・・@division="3"の次のdivision="1"は白を表示


新宿は京王線をごらんください
黒 ・・・・・・・・・・・・・・・・Adivision="2"の次のdivision="1"はその前
白                  のdivision="1"が(白→黒、黒→白)を表示



吉祥寺は井の頭線をごらんください


京王線




<スタイルシート>
<!-- 一部省略 -->
<xsl:template match="page">
<xsl:for-each select=".">
<xsl:call-template name="obi"/>
</xsl:for-each>
</xsl:template>

<xsl:template name="obi">
<xsl:param name="x"/>
<xsl:param name="y" select="1"/>
<xsl:param name="z">
<xsl:choose>
<xsl:when test="object/@division = '1'">
<xsl:value-of select="1"/>
</xsl:when>
<xsl:when test="object/@division = '2'">
<xsl:value-of select="2"/>
</xsl:when>
<xsl:when test="object/@division = '3'">
<xsl:value-of select="3"/>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:if test="$y <= '8'">
<xsl:if test="$z = '1'">
<xsl:value-of select="object"/>
<xsl:call-template name="obi">
<xsl:with-param name="x" select="1"/>
<xsl:with-param name="y" select="string($y + 1)"/>
</xsl:call-tem-plate>
</xsl:if>
<xsl:if test="$z = '2'">
<xsl:value-of select="object"/>
<xsl:call-template name="obi">
<xsl:with-param name="x" select="$x"/>
<xsl:with-param name="y" select="string($y + 1)"/>
</xsl:call-tem-plate>
</xsl:if>
<xsl:if test="$z = '3'">
<xsl:if test="$x = '1'">
<xsl:text>白</xsl:text>
<xsl:call-template name="obi">
<xsl:with-param name="x" select="2"/>
<xsl:with-param name="y" select="string($y + 1)"/>
</xsl:call-tem-plate>
</xsl:if>
<xsl:if test="$x = '2'">
<xsl:text>黒</xsl:text>
<xsl:call-template name="obi">
<xsl:with-param name="x" select="1"/>
<xsl:with-param name="y" select="string($y + 1)"/>
</xsl:call-tem-plate>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:template>

よろしくお願いします。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2002-07-28 14:22
逐次「書き換わる変数」は 使えませんから
方針としては
解1
出現済みの division="1" を countして 偶奇を 判定
解2
自分の id を取得して divison="1" のリストの中の位置を知る
あたりでしょう。階層をまたぐのはどうするか

[ メッセージ編集済み 編集者: MMX 編集日時 2002-07-28 14:23 ]
tsuyoshi
会議室デビュー日: 2002/07/27
投稿数: 3
投稿日時: 2002-07-28 18:38
MMXさん返答ありがとうございます。

>逐次「書き換わる変数」は 使えませんから
やはりそうですよね。このままでは変数がバインドされずうまくいきませんでした。

>解1
>出現済みの division="1" を countして 偶奇を 判定
>解2
>自分の id を取得して divison="1" のリストの中の位置を知る
>あたりでしょう。階層をまたぐのはどうするか
ちなみに解1と解2の各々のスタイルシートはどのようにかけばよいでしょうか?
なまちゅ
会議室デビュー日: 2002/07/26
投稿数: 6
投稿日時: 2002-07-29 14:08
こんにちは。
横やりですがちょいと書いてみました。
こんなもんでどうでしょうか?
最初にdivision=1が出てきたときは黒にしてみました。
それから勝手にルートノードpagelistをつけました。

>MMXさん
気になるところがあったら突っ込みお願いします。
MMXさんが言ってたのとはちょっと違いますかね?

コード:
<?xml version="1.0" encoding="shift_jis"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="shift_jis"/>

<xsl:template match="/">
  <xsl:apply-templates select="pagelist/page"/>
</xsl:template>

<xsl:template match="page">
  <xsl:call-template name="loop">
    <xsl:with-param name="i" select="1"/>
    <xsl:with-param name="flag" select="0"/>
  </xsl:call-template>
  <xsl:text>
</xsl:text>
</xsl:template>

<xsl:template name="loop">
  <xsl:param name="i"/>
  <!--
    変数flag
    0:division=1,白
    1:division=1,黒
    2:division=2
    3:division=3
  -->
  <xsl:param name="flag"/>
  <xsl:choose>
    <xsl:when test="object[$i]/@division = '1'">
      <xsl:choose>
        <xsl:when test="$flag = 0 or $flag = 2">
          <xsl:text>黒
</xsl:text>
          <xsl:call-template name="loop">
            <xsl:with-param name="i" select="$i + 1"/>
            <xsl:with-param name="flag" select="1"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:when test="$flag = 1 or $flag = 3">
          <xsl:text>白
</xsl:text>
          <xsl:call-template name="loop">
            <xsl:with-param name="i" select="$i + 1"/>
            <xsl:with-param name="flag" select="0"/>
          </xsl:call-template>
        </xsl:when>
      </xsl:choose>
    </xsl:when>
    <xsl:when test="object[$i]/@division = '2'">
      <xsl:value-of select="object[$i]"/>
      <xsl:text>
</xsl:text>
      <xsl:call-template name="loop">
        <xsl:with-param name="i" select="$i + 1"/>
        <xsl:with-param name="flag" select="2"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:when test="object[$i]/@division = '3'">
      <xsl:value-of select="object[$i]"/>
      <xsl:text>
</xsl:text>
      <xsl:call-template name="loop">
        <xsl:with-param name="i" select="$i + 1"/>
        <xsl:with-param name="flag" select="3"/>
      </xsl:call-template>
    </xsl:when>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2002-07-29 21:57
oddeven.xml ----- テストデータ
<?xml version="1.0" encoding="Shift_JIS" standalone="yes"?>
<pages>
<page>
<object division="3">中央線</object>
<object division="1">新宿</object>
<object division="1">新宿</object>
<object division="1">新宿</object>
<object division="2">新宿は京王線をごらんください</object>
<object division="1">吉祥寺</object>
<object division="1">吉祥寺</object>
<object division="1">吉祥寺</object>
</page>
<page>
<object division="1">吉祥寺</object>
<object division="2">吉祥寺は井の頭線をごらんください</object>
<object division="1">八王子</object>
<object division="1">八王子</object>
<object division="3">京王線</object>
<object division="1">八王子</object>
<object division="1">八王子</object>
<object division="1">八王子</object>
</page>
<page>
<object division="2">小田急線</object>
<object division="1">八王子</object>
<object division="1">八王子</object>
<object division="3">京王線</object>
<object division="1">八王子</object>
<object division="1">八王子</object>
<object division="1">八王子</object>
<object division="1">吉祥寺</object>
</page>
</pages>
--------------- oddeven.xsl
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="Shift_JIS"/>

<xsl:template match="/">
<xsl:apply-templates select="pages/page"/>
</xsl:template>

<xsl:template match="page">
<xsl:call-template name="loop">
<xsl:with-param name="i" select="1"/>
<xsl:with-param name="flag" select="count(preceding-sibling::page/object[@division=1]) mod 2"/> </xsl:call-template>
<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template name="loop">
<xsl:param name="i"/>
<!--
変数flag 次の着色指定
0:division=1,白
1:division=1,黒
-->
<xsl:param name="flag"/>
<xsl:choose>
<xsl:when test="object[$i]/@division = '1'">
<xsl:choose>
<xsl:when test="$flag = 0">
<xsl:text>白
</xsl:text>
<xsl:call-template name="loop">
<xsl:with-param name="i" select="$i + 1"/>
<xsl:with-param name="flag" select="1"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$flag = 1">
<xsl:text>黒
</xsl:text>
<xsl:call-template name="loop">
<xsl:with-param name="i" select="$i + 1"/>
<xsl:with-param name="flag" select="0"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:when>
<xsl:when test="object[$i]/@division = '2'">
<xsl:value-of select="object[$i]"/>
<xsl:text>
</xsl:text>
<xsl:call-template name="loop">
<xsl:with-param name="i" select="$i + 1"/>
<xsl:with-param name="flag" select="$flag"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="object[$i]/@division = '3'">
<xsl:value-of select="object[$i]"/>
<xsl:text>
</xsl:text>
<xsl:call-template name="loop">
<xsl:with-param name="i" select="$i + 1"/>
<xsl:with-param name="flag" select="$flag"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>
-------------------------------------

やはり、再帰で継続する変数の実現が自然なのですが
これをやってしまうと、
XSLTへの悪口(顰蹙)を起こしてしまうので良し悪しだ。
再帰も慣れなのだが、行数増加で美しくないのはどうしようもない。

「なまちゅ」の初版の実行結果は
中央線



新宿は京王線をごらんください





吉祥寺は井の頭線をごらんください


京王線




でページまたぎのところでリズムがつながりません。
page 単位の処理なので当然です、ここが山場でしょう。

できてはいると思うが、わかりやすさ、処理スピード
ともに納得いくかどうかは不明です。
なまちゅ
会議室デビュー日: 2002/07/26
投稿数: 6
投稿日時: 2002-07-29 23:35
MMXさんフォローありがとうございます。
だめですね。こんな若輩者がいっちょまえに人の質問に答えようなんざ10年早いですね(^_^;

><xsl:with-param name="flag" select="count(preceding-sibling::page/object[@division=1]) mod 2"/> </xsl:call-template>

省略ばかり使っててaxisなんて忘れてました。。。
まだ数回の書き込みですが、いろいろ勉強になります。

>やはり、再帰で継続する変数の実現が自然なのですが
>これをやってしまうと、
>XSLTへの悪口(顰蹙)を起こしてしまうので良し悪しだ。
>再帰も慣れなのだが、行数増加で美しくないのはどうしようもない。

XSLTへの悪口ってどういうことですか?

>でページまたぎのところでリズムがつながりません。
>page 単位の処理なので当然です、ここが山場でしょう。

おーそうですね。気づかなかった。。。
前の書き込みで言われてたのはそういうことですね。

>できてはいると思うが、わかりやすさ、処理スピード
>ともに納得いくかどうかは不明です。

処理スピードというのはどういう処理をすると遅くなるとかいう指針はあるのですかね?
ご存知でしたら、いくつかご教授願えませんでしょうか?

質問ばかりになってしまいまして、すみません。
tsuyoshi
会議室デビュー日: 2002/07/27
投稿数: 3
投稿日時: 2002-07-30 00:26
MMXさん、なまちゅさん、おつかれさまです。

ほぼできあがってますが、ページをまたがるのがむずかしそうですね。
そんなに簡単にはできない代物みたいですね。
この際、力技でもかまわないとおもいます。
もう少しお二人さまのを参考に作りこみをしたいと思います。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2002-07-30 09:55
>XSLTへの悪口ってどういうことですか?
単純なテンプレート展開はわかりやすく書けるが
プログラム的な操作機能は大変弱いため、それをしようとすると
行数が2倍以上になる。(XSLT 誕生時の要求がそのようだったから)
XSLT2.0 ではグループ処理が強化予定らしいですが。

>処理スピードというのはどういう処理をすると遅くなるとかいう指針はあるのですかね?
XSLTの実装は進化中だからそれぞれです。普通のプログラムと同様に
アルゴリズム(計算のオーダー)、多重の同じ処理、文字列の切り貼り
あたりをイメージできれはよいのでは。

一段のXSLT の中で全部をせずに、XMLパイプライン処理(コクーン2など各種)
でUNIXのコマンドイメージで多段でするとか、
(pullパーサー)DOM操作 で素材を準備してXSLTで一括展開を組み合わせるとか
いろいろ対策はあるでしょう。

スキルアップ/キャリアアップ(JOB@IT)