初めまして。へいです。思うところがあり、はてなブログから移転してきました。よろしくお願いいたします。

 玄人プログラマーからしたら当たり前のことなのかもしれないが、私のような駆け出しプログラマーのために残すという意味合いと、自分自身のメモのために残します。

 

 今回取り掛かった問題はXMLとXSLについてです。問題としても単純明快で、「XSLを使ってXMLを表示させる」というものです。

 例えば、以下の単純なXML文章があったとする。
 
XML
<全体>
 <題名>テスト01</題名>
 <情報>
  <品名>うどん</品名>
  <単価>100</単価>
  <備考>おいしいうどん</備考>
 </情報>
 <情報>
  <品名>にくうどん</品名>
  <単価>150</単価>
  <備考>肉の分だけ高い</備考>
 </情報>
</全体>
 
 ただ、「うどん」という商品と「にくうどん」という商品の単価と備考が記述されているだけの単純明快なものである。これをXSLを使って表示させようとしたとき、ほかのWEBサイトを参考にしながらコーディングを行うと、私のような駆け出しは下記のように記述する(と思う)。
 
XSL:for-eachを使用 <?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" version="4.01" encoding="Shift_JIS" standalone="yes" indent="yes" />
<xsl:template match="/">
<html lang="ja">
<head><title><xsl:value-of select="全体/題名" /></title></head> <!--タイトル表示-->
<body>
 <div>
  <h1><xsl:value-of select="全体/題名" /></h1>  <!--意味も無くタイトルを再度表示する-->    
  <xsl:apply-templates select="全体" />  <!--"全体"テンプレートを適用する-->
 </div>
</body>
</html>
</xsl:template>
<xsl:template match="全体">   <!--"全体"テンプレート-->
 <table border="1">    <!--"表を作成-->
  <tr>
   <th>品名</th>
   <th>単価</th>
   <th>備考</th>
  </tr>
  <xsl:for-each select="情報">   <!--for-eachを使用したループ-->
  <tr>
   <th><xsl:value-of select="品名" /></th> <!--表示したい項目-->
   <td><xsl:value-of select="単価" /></td>
   <td><xsl:value-of select="備考" /></td>
  </tr>
  </xsl:for-each>
 </table>
</xsl:template>
</xsl:stylesheet>
 
 意味も無くタイトルを再度表示しようとするところが、駆け出しっぽいところである。コーディング中のイメージとしては、「一つの<情報>タグを一行として、ループさせて、表示する」というものである。上記のようなXMLとXSLを作成すると、下記のような結果が得られる。(IE実行)
 

f:id:atwgwu:20170508213719p:plain

 
 私のようなあんぽんたんには理解し難いことなのだが、上記のような書き方はXSLを正しく使えていないのかもしれないのだ。上述のXSL文章を以下の等価な文章に置き換えることができる。
 
XSL:for-eachを使わない
<!--省略-->
<body>
<div>
 <h1><xsl:value-of select="全体/題名" /></h1>
 <table border="1">
  <tr>
   <th>品名</th>
   <th>単価</th>
   <th>備考</th>
  </tr>
  <xsl:apply-templates select="全体/情報" />
 </table>
</div>
</body>
</html>
</xsl:template>
<xsl:template match="情報">
  <tr>
   <td><xsl:value-of select="品名" /></td>
   <td><xsl:value-of select="単価" /></td>
   <td><xsl:value-of select="備考" /></td>
  </tr>
</xsl:template>
</xsl:stylesheet>
 
 最初、上述のXSLを見たとき、「は?」と思った。「だって、ループ文ないじゃん!いみぷ~」というのが率直な感想である。私のような元C言語プログラマーからすると、理解し難いのではないだろうか。
 
 <xsl:apply-templates select="全体/情報" />の部分で、<body>タグ内は役目を終えたと思ってよい(いやだめかも)。そして、<xsl:templete match="情報">という文章はなんとなく、「XML文章の<情報>というタグをすべて抜き出せ」と見えなくもない。なんたって、"テンプレートマッチ"って書いてあるんだから。(画像処理プログラマーだった私はなんとなくそう思えた)つまり、<xsl:templete match="情報">という一行は、「<情報>というキーワードを用いてXML文章内でマッチングを行い、マッチングしたものはすべて抽出しろ」という意味なのではないか。
 
まだよくわからないけど、やばいなXML