二つのテーブルを一つにまとめる
はじめに
二つのテーブルを一つにまとめるxsltを考える.具体的には、以下のin.htmlの中にあるtable1とtable2をまとめて、out.htmlのtable3を作成する.table1とtable2の行を同期を取って一緒に取り出せれば良い.
<!-- in.html -->
<html>
<table id="table1" border="1">
<caption>table1</caption>
<tr><td>a</td></tr>
<tr><td>b</td></tr>
<tr><td>c</td></tr>
</table>
<table id="table2" border="1">
<caption>table2</caption>
<tr><td>10</td></tr>
<tr><td>20</td></tr>
<tr><td>30</td></tr>
</table>
</html>
<!-- out.html -->
<?xml version="1.0" encoding="utf-8"?>
<html>
<table id="table3" border="1">
<caption>table3</caption>
<tr>
<td>a</td>
<td>10</td>
</tr>
<tr>
<td>b</td>
<td>20</td>
</tr>
<tr>
<td>c</td>
<td>30</td>
</tr>
</table>
</html>
in.html
a |
b |
c |
10 |
20 |
30 |
out.html
a | 10 |
b | 20 |
c | 30 |
変数を使う
table1の行数を変数に保管し、table2の該当行を取り出すやり方である.分かりやすい.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output
indent="yes"
method="xml"
encoding="utf-8"/>
<xsl:template match="/">
<html>
<table id="table3" border="1">
<caption>table3</caption>
<xsl:apply-templates select="/html/table[@id='table1']/tr"/>
</table>
</html>
</xsl:template>
<xsl:template match="tr">
<tr>
<xsl:variable name="pos" select="position()"/> <!-- table1のカレントノードの行数を変数posに格納 -->
<td><xsl:value-of select="td"/></td>
<td><xsl:value-of select="//table[@id='table2']/tr[$pos]/td"/></td> <!-- table1から同じ行数を取り出す -->
</tr>
</xsl:template>
</xsl:stylesheet>
変数を使わない
変数を使わない書き方もできる.current関数とpreceding-siblingを使う.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output
indent="yes"
method="xml"
encoding="utf-8"/>
<xsl:template match="/">
<html>
<table id="table3" border="1">
<caption>table3</caption>
<xsl:apply-templates select="/html/table[@id='table1']/tr"/>
</table>
</html>
</xsl:template>
<xsl:template match="tr">
<tr>
<td><xsl:value-of select="td"/></td>
<td><xsl:value-of select="//table[@id='table2']/tr[count(current()/preceding-sibling::*)+1]/td"/></td>
<!-- current()が必要.コンテキストノードが//table[@id='table2']/trになるので、currnet()を付けてカレントノード//table[@id='table1']/trを明示して行数を取得する.-->
</tr>
</xsl:template>
</xsl:stylesheet>
実行環境
- PC-BSD 10.3
- Xalan Java 2.7.2
参考
Use position of current node to access value of another node