XSLTで単票形式と一覧形式を相互に変換

###やりたいこと

以下のような単票と一覧をXSLで相互に変換したい。

- 【単票形式】

<table border="1">
<tr><th>商品番号</th><td>103</td></tr>
<tr><th>商品名</th><td>ジャガイモ</td></tr>
<tr><th>単価</th><td>80</td></tr>
<tr><th>在庫</th><td>150</td></tr>
<tr><th>備考</th><td>ナス科ナス属<br/>ポテトチップス<br/>肉じゃが</td></tr>
</table>

- 【一覧形式】

<table>
<tr><th>商品番号</th><th>商品名</th><th>単価</th><th>在庫</th><th>備考</th></tr>
<tr><td>103</td><td>ジャガイモ</td><td>80</td><td>150</td><td>ナス科ナス属<br/>ポテトチップス<br/>肉じゃが</td></tr>
</table>


###XHTML【単票形式】

```html:cuts.xml
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="to_list.xsl"?>
<html xml:lang="jp" lang="jp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>単票形式</title>
<meta charset="utf-8" />
</head>
<body>
<table border="1">
<tr><th>商品番号</th><td>101</td></tr>
<tr><th>商品名</th><td>タマネギ</td></tr>
<tr><th>単価</th><td>60</td></tr>
<tr><th>在庫</th><td>250</td></tr>
<tr><th>備考</th><td>
ユリ科ネギ属<br/>
パタリロ
</td></tr>
</table>
<hr/>
<table border="1">
<tr><th>商品番号</th><td>102</td></tr>
<tr><th>商品名</th><td>ニンジン</td></tr>
<tr><th>単価</th><td>90</td></tr>
<tr><th>在庫</th><td>100</td></tr>
<tr><th>備考</th><td>セリ科ニンジン属</td></tr>
</table>
<hr/>
<table border="1">
<tr><th>商品番号</th><td>103</td></tr>
<tr><th>商品名</th><td>ジャガイモ</td></tr>
<tr><th>単価</th><td>80</td></tr>
<tr><th>在庫</th><td>150</td></tr>
<tr><th>備考</th><td>
ナス科ナス属<br/>
ポテトチップス<br/>
肉じゃが
</td></tr>
</table>
</body>
</html>
```

###XSL【単票形式 ⇒ 一覧形式】

```xml:to_list.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:x="http://www.w3.org/1999/xhtml"
  xmlns="http://www.w3.org/1999/xhtml"
  exclude-result-prefixes="x"
  >

  <xsl:output method="xml" encoding="utf-8" indent="yes" />

  <xsl:template match="//processing-instruction()">
    <xsl:processing-instruction name="xml-stylesheet">type="text/xsl" href="to_cuts.xsl"</xsl:processing-instruction>
  </xsl:template>

  <xsl:template match="x:title">
    <xsl:copy>
      <xsl:text>一覧形式</xsl:text>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="x:body">
    <xsl:copy>
      <table border="1">
        <!-- 見出し行 -->
        <tr>
          <xsl:apply-templates select="//x:table[1]//x:tr" >
            <xsl:with-param name="p.th" select="true()"/>
          </xsl:apply-templates>
        </tr>
        <!-- データ行 -->
        <xsl:apply-templates select="node()|@*" />
      </table>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="x:table">
    <!-- データ行 -->
    <tr>
      <!-- tbodyがある場合を考慮して、"//"としておく -->
      <xsl:apply-templates select=".//x:tr" />
    </tr>
  </xsl:template>

  <xsl:template match="x:tr">
    <xsl:param name="p.th"/>
    <xsl:choose>
      <xsl:when test="false()"></xsl:when>
<!-- 指定項目を表示したくない場合、有効にする。この場合は、5列目（備考）が表示されなくなる
      <xsl:when test="position()= 5"></xsl:when>
-->
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="$p.th">
            <xsl:apply-templates select="x:th" />
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates select="x:td" />
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- hr タグは破棄する -->
  <xsl:template match="x:hr">
  </xsl:template>

  <xsl:template match="x:meta|x:br">
    <xsl:copy-of select="."/>
  </xsl:template>

  <!-- 要素・属性をコピー -->
  <xsl:template match="/|node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
<!--
msxsl cuts.xml to_list.xsl -o list_out.xml
-->
```

###XHTML【一覧形式】

```html:list.xml
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="to_cuts.xsl"?>
<html xml:lang="jp" lang="jp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>一覧形式</title>
<meta charset="utf-8" />
</head>
<body>
<table border="1">
<tr><th>商品番号</th><th>商品名</th><th>単価</th><th>在庫</th><th>備考</th></tr>
<tr><td>101</td><td>タマネギ</td><td>60</td><td>250</td><td>ユリ科ネギ属<br/>パタリロ</td></tr>
<tr><td>102</td><td>ニンジン</td><td>90</td><td>100</td><td>セリ科ニンジン属</td></tr>
<tr><td>103</td><td>ジャガイモ</td><td>80</td><td>150</td><td>ナス科ナス属<br/>ポテトチップス<br/>肉じゃが</td></tr>
</table>
</body>
</html>
```

###XSL【一覧形式 ⇒ 単票形式】

```xml:to_cuts.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:x="http://www.w3.org/1999/xhtml"
  xmlns="http://www.w3.org/1999/xhtml"
  exclude-result-prefixes="x"
  >

  <xsl:output method="xml" encoding="utf-8" indent="yes" />

  <xsl:template match="//processing-instruction()">
    <xsl:processing-instruction name="xml-stylesheet">type="text/xsl" href="to_list.xsl"</xsl:processing-instruction>
  </xsl:template>

  <xsl:template match="x:title">
    <xsl:copy>
      <xsl:text>単票形式</xsl:text>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="x:table">
    <xsl:apply-templates select=".//x:tr" />
  </xsl:template>

  <xsl:template match="x:tr">
    <xsl:if test="position()!=1">
      <table border="1">
        <xsl:apply-templates select="x:td" />
      </table>
      <xsl:if test="position()!=last()">
        <hr/>
      </xsl:if>
    </xsl:if>
  </xsl:template>

  <xsl:template match="x:td">
    <xsl:variable name="v.pos" select="position()" />
    <xsl:choose>
      <xsl:when test="false()"></xsl:when>
<!-- 指定項目を表示したくない場合、有効にする。この場合は、5行目（備考）が表示されなくなる
      <xsl:when test="$v.pos= 5"></xsl:when>
-->
      <xsl:otherwise>
        <tr>
          <xsl:apply-templates select="//x:th[$v.pos]" />
          <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
          </xsl:copy>
        </tr>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="x:meta|x:br">
    <xsl:copy-of select="."/>
  </xsl:template>

  <!-- 要素・属性をコピー -->
  <xsl:template match="/|node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
<!--
msxsl list.xml to_cuts.xsl -o cuts_out.xml
-->
```