XSL:for-eachで添字を持たせてお隣要素も参照してみた

未だ何かとスムーズに使えないXSL。
同じノード下の隣の要素の値を参照しつつ文字列を作ろうとして
だいぶはまったのでメモをば。

ちなみにXSLのテストは、
XSLエディタ:http://la.ma.la/misc/xsltedit/
が便利で最近使ってます。
コメントが入っていると挙動がおかしいときがあるようですが、とりあえずは。


————————————————————————
こんな感じのXMLから。。。。
————————————————————————

<Root>
<Sub>
<company>○○株式会社</company>
<list>
<!-- person -->
<name>山田</name>
<name2>さん</name2>
<img>imageFileA</img>
<img2>jpg</img2>
<!-- person -->
<name>佐々木</name>
<name2>くん</name2>
<img>imageFileB</img>
<img2>eps</img2>
</list>
</Sub>
<Sub>
<company>株式会社○○</company>
<list>
<name>田中</name>
<name2>さん</name2>
<img>imageFileC</img>
<img2>ai</img2>
</list>
</Sub>
<Sub>
<company>○○カンパニー</company>
<list>
<name>加藤</name>
<name2>様</name2>
<img>imageFileA</img>
<img2>jpg</img2>
<name>佐藤</name>
<name2>殿</name2>
<img>imageFileD</img>
<img2>psd</img2>
<name>石井</name>
<name2>さん</name2>
<img>imageFileB</img>
<img2>eps</img2>
</list>
</Sub>
・
・
・
</Root>

————————————————————————

————————————————————————
こんな様なXMLを作りたいと思う。。。
————————————————————————

<Root>
<person>
<atena>○○株式会社|山田 さん</atena>
<img href="file:///imgs/imageFileA.jpg" />
</person>
<person>
<atena>○○株式会社|佐々木 くん</atena>
<img href="file:///imgs/imageFileB.eps" />
</person>
<person>
<atena>株式会社○○|田中 さん</atena>
<img href="file:///imgs/imageFileC.ai" />
</person>
<person>
<atena>○○カンパニー|加藤 様</atena>
<img href="file:///imgs/imageFileA.jpg" />
</person>
<person>
<atena>○○カンパニー|佐藤 殿</atena>
<img href="file:///imgs/imageFileD.psd" />
</person>
<person>
<atena>○○カンパニー|石井 さん</atena>
<img href="file:///imgs/imageFileB.eps" />
</person>
・
・
・
</Root>

————————————————————————

最初から人ごとにブロックになってくれてれば良かったんだけど、内が並列なので苦戦。

まずだけすべて取り出す方法は分っていたので、
ソレと同じ添字のノードを捕まえれば良いと考えた。
さんざん試した末に↓のXSLができました!
もっと単純にできるのかな?

————————————————————————
変換XSL
————————————————————————

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<Root>
<sub>
<xsl:call-template name="tmpatena" /><xsl:text>
</xsl:text>
</sub>
</Root>
</xsl:template>
<!-- 宛名作成テンプレート -->
<xsl:template name="tmpatena">
<!-- デバッグ用 <xsl:text>★count of name = </xsl:text><xsl:value-of select="count(//name)" /><xsl:text>
</xsl:text> -->
<xsl:for-each select="/Root/Sub">
<xsl:variable name="i" select="position()"/>
<!-- デバッグ用 <xsl:text>★position sub = </xsl:text><xsl:value-of select="$i" /><xsl:text>
</xsl:text> -->
<!-- デバッグ用 <xsl:text>★count of name in this Sub = </xsl:text><xsl:value-of select="count(/Root/Sub[$i]/list/name)" /><xsl:text>
</xsl:text> -->
<xsl:for-each select="/Root/Sub[$i]/list/name">
<xsl:variable name="j" select="position()"/>
<!-- デバッグ用 <xsl:text>★position name = </xsl:text><xsl:value-of select="$j" /><xsl:text>
</xsl:text> -->
<person>
<atena>
<xsl:value-of select="concat(../../company, '|', ., ' ', /Root/Sub[$i]/list/name2[$j])" />
</atena><xsl:text>
</xsl:text>
<img>
<xsl:attribute name="href">
<xsl:text>file:///imgs/</xsl:text>
<xsl:value-of select="concat(/Root/Sub[$i]/list/img[$j], '.', /Root/Sub[$i]/list/img2[$j])" />
</xsl:attribute>
</img><xsl:text>
</xsl:text>
</person>
</xsl:for-each>
</xsl:for-each>
</xsl:template>

————————————————————————

今回のXSLでの発見wは「foreach」×「position()」。
指定回数繰り返すのもコレでできる!
という事を↓のサイトで知りました〜
http://www5e.biglobe.ne.jp/~access_r/hp/dhtml/dhtml_xml_009.html
■こちらはDHTMLを扱ってらっしゃるページ。その他JavaSicriptなどなどもホームから。
そか、DHTMLでもXSL使ったら幅が広がってたんだ〜と、色々教えていただきました。

なぜにかforeach内で自分のノード()を取るのが「.」というのに思い至らず、ソコでも時間を食のはもったいなかったな。。。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください