固定長データ
Posted feedbacks - XSLT
単純にデータを読み込んで、XML 形式に転写する だけですぅ。 こんな簡単なことするだけでも XSLT だとこんなに長くなるんだろか? XSLT 初心者の 僕にはわかんないやぁ~ データは XML ファイルで与えます。ルートノードの 直下に 文字列を書きます。ルートノードの名前 は SerializedRecords にする。 そそ、Array っていうオブジェクトを (仮想的に) 定 義しました。 Array_push 関数 (ほんとはテンプ レート) で データ追加するだけ。これ定義するだけ でも行数つかったぁ。。。 もっとエレガントなやり方あんのかもしれない。 だれか教えて~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | <?xml version="1.0" encoding="Shift_JIS" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- ==========================================================================
定数の設定
=========================================================================== -->
<xsl:variable name="姓_length" select="12" />
<xsl:variable name="名_length" select="12" />
<xsl:variable name="性別_length" select="1" />
<xsl:variable name="年齢_length" select="3" />
<xsl:variable name="年_length" select="4" />
<xsl:variable name="月_length" select="2" />
<xsl:variable name="日付_length" select="2" />
<xsl:variable name="朝食のメニュー_length" select="500" />
<xsl:variable name="昼食のメニュー_length" select="500" />
<xsl:variable name="夕食のメニュー_length" select="500" />
<xsl:variable name="姓_offset" select="1" />
<xsl:variable name="名_offset" select="$姓_offset + $姓_length" />
<xsl:variable name="性別_offset" select="$名_offset + $名_length" />
<xsl:variable name="年齢_offset" select="$性別_offset + $性別_length" />
<xsl:variable name="年_offset" select="$年齢_offset + $年齢_length" />
<xsl:variable name="月_offset" select="$年_offset + $年_length" />
<xsl:variable name="ヘッダー_length" select="$姓_length + $名_length + $性別_length + $年齢_length + $年_length + $月_length" />
<xsl:variable name="日付_offset" select="1" />
<xsl:variable name="朝食のメニュー_offset" select="$日付_offset + $日付_length" />
<xsl:variable name="昼食のメニュー_offset" select="$朝食のメニュー_offset + $朝食のメニュー_length" />
<xsl:variable name="夕食のメニュー_offset" select="$昼食のメニュー_offset + $昼食のメニュー_length" />
<xsl:variable name="一日のメニュー_length" select="$日付_length + $朝食のメニュー_length + $昼食のメニュー_length + $夕食のメニュー_length" />
<!-- ==========================================================================
メインルーチン
=========================================================================== -->
<xsl:template match="/">
<xsl:call-template name="stringToRecords">
<xsl:with-param name="string" select="/SerializedRecords/text ()" />
<xsl:with-param name="人数" select="500" />
</xsl:call-template>
</xsl:template>
<!-- ==========================================================================
Array オブジェクトの定義
(タグの名前はなんでも良かったので HTML にある ol と li にした)
=========================================================================== -->
<xsl:template name="new_Array">
<ol />
</xsl:template>
<xsl:template name="Array_push">
<xsl:param name="array" />
<xsl:param name="element" />
<ol>
<xsl:for-each select="$array/ol/li">
<xsl:copy-of select="." />
</xsl:for-each>
<li><xsl:copy-of select="$element" /></li>
</ol>
</xsl:template>
<!-- ==========================================================================
stringToRecords: レコードデータの読み込み
人数 分だけ レコード を読み込みだけ。ただし、メニューのところは別関数で...
=========================================================================== -->
<xsl:template name="stringToRecords">
<xsl:param name="string" />
<xsl:param name="人数" />
<xsl:call-template name="stringToRecords_">
<xsl:with-param name="string" select="$string" />
<xsl:with-param name="records">
<xsl:call-template name="new_Array" />
</xsl:with-param>
<xsl:with-param name="人数" select="$人数" />
</xsl:call-template>
</xsl:template>
<xsl:template name="stringToRecords_">
<xsl:param name="string" />
<xsl:param name="records" />
<xsl:param name="人数" />
<xsl:choose>
<xsl:when test="$人数 = 0">
<xsl:copy-of select="$records" />
</xsl:when>
<xsl:otherwise>
<!-- 日数 は本来ならその月にあわせて変化させるんだろぉなぁ -->
<xsl:variable name="日数" select="31" />
<!-- タグの名前は何でも良かったので HTML の table 形式にした。 -->
<xsl:variable name="record">
<table><tbody>
<tr><td>姓</td><td><xsl:value-of select="substring ($string, $姓_offset, $姓_length)" /></td></tr>
<tr><td>名</td><td><xsl:value-of select="substring ($string, $名_offset, $名_length)" /></td></tr>
<tr><td>性別</td><td><xsl:value-of select="substring ($string, $性別_offset, $性別_length)" /></td></tr>
<tr><td>年齢</td><td><xsl:value-of select="substring ($string, $年齢_offset, $年齢_length)" /></td></tr>
<tr><td>年</td><td><xsl:value-of select="substring ($string, $年_offset, $年_length)" /></td></tr>
<tr><td>月</td><td><xsl:value-of select="substring ($string, $月_offset, $月_length)" /></td></tr>
<tr><td>各日のメニュー</td>
<td>
<xsl:call-template name="stringToMenues">
<xsl:with-param name="string" select="substring ($string, $ヘッダー_length + 1)" />
<xsl:with-param name="日数" select="$日数" />
</xsl:call-template>
</td>
</tr>
</tbody></table>
</xsl:variable>
<!-- これまで読み込んだデータ $records に 今読み込んだデータ $record を 追加~ -->
<xsl:variable name="records_">
<xsl:call-template name="Array_push">
<xsl:with-param name="array" select="$records" />
<xsl:with-param name="element" select="$record" />
</xsl:call-template>
</xsl:variable>
<!-- 人数分だけ再帰~。もちろんこれまでのデータ $records_ も渡す... -->
<xsl:call-template name="stringToRecords_">
<xsl:with-param name="string" select="substring ($string, $ヘッダー_length + $日数 * $一日のメニュー_length + 1)" />
<xsl:with-param name="records" select="$records_" />
<xsl:with-param name="人数" select="$人数 - 1" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- ==========================================================================
stringToMenues: 一日のメニューの読み込み
固定長のものを 日数 回数 単純に 繰り返し読み込むだけ...
=========================================================================== -->
<xsl:template name="stringToMenues">
<xsl:param name="string" />
<xsl:param name="日数" />
<xsl:call-template name="stringToMenues_">
<xsl:with-param name="string" select="$string" />
<xsl:with-param name="日数" select="$日数" />
<xsl:with-param name="menues">
<xsl:call-template name="new_Array" />
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="stringToMenues_">
<xsl:param name="string" />
<xsl:param name="日数" />
<xsl:param name="menues" />
<xsl:choose>
<xsl:when test="$日数 = 0">
<xsl:copy-of select="$menues" />
</xsl:when>
<xsl:otherwise>
<!-- タグの名前は何でも良かったので HTML の table 形式にした。 -->
<xsl:variable name="menu">
<table><tbody>
<tr><td>日付</td><td><xsl:value-of select="substring ($string, $日付_offset, $日付_length)" /></td></tr>
<tr><td>朝食のメニュー</td><td><xsl:value-of select="substring ($string, $朝食のメニュー_offset, $朝食のメニュー_length)" /></td></tr>
<tr><td>昼食のメニュー</td><td><xsl:value-of select="substring ($string, $昼食のメニュー_offset, $昼食のメニュー_length)" /></td></tr>
<tr><td>夕食のメニュー</td><td><xsl:value-of select="substring ($string, $夕食のメニュー_offset, $夕食のメニュー_length)" /></td></tr>
</tbody></table>
</xsl:variable>
<!-- これまで読み込んだデータ $menues に 今読み込んだデータ $menu を 追加~ -->
<xsl:variable name="menues_">
<xsl:call-template name="Array_push">
<xsl:with-param name="array" select="$menues" />
<xsl:with-param name="element" select="$menu" />
</xsl:call-template>
</xsl:variable>
<!-- 日数分だけ再帰~。もちろんこれまでのデータ $menues_ も渡す... -->
<xsl:call-template name="stringToMenues_">
<xsl:with-param name="string" select="substring ($string, $一日のメニュー_length + 1)" />
<xsl:with-param name="日数" select="$日数 - 1" />
<xsl:with-param name="menues" select="$menues_" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
|

Mymelo #6060() Rating5/7=0.71
固定長のデータが記載されたファイルを読み込むプログラムを作成してください。読み込んだデータは、複数の値を格納できるデータ型に格納してください。
ファイルには、すべて ascii 文字で以下のデータが格納されています。デリミタはなく、固定長で格納されています。レコードとレコードのあいだも改行はありません。
以上の形式のデータ500人分を読みこんで、データを複数の値を格納できるデータ型に格納してください。データに大して何か処理を行う必要はなく、すぐに破棄してかまいません。
この問題は、このようなファイルをどのように扱うかを知りたくて作成しました。
[ reply ]