dポイントプレゼントキャンペーン実施中!

XMLをXSLでHTMLを生成しています。

変数$whereにある店の部分名を入力して
その店の扱う商品を表示したいと思っています。

しかし、以下の例だと
チョコレート


うめぼし
のようになってしまいます。

チョコレート

うめぼし
のように表示するにはどうすればよいでしょうか?

ご教授ください。

XMLが以下のようになっています。
()は要素の中身
list
item
title(チョコレート)
value(200円)
  shops
shop(○○ストア)
   shop(スーパー△△)
  shop(駄菓子屋□□)
 item
title(本)
  value(1000円)
  shops
shop(○○ブックス)
   shop(△△百貨店)
   shop(スーパー△△)
 item
title(うめぼし)
  value(100円)
  shops
shop(スーパー○○)
   shop(△△百貨店)
   shop(通販○○)
list

そしてXSLは
<xsl:apply-templates select="list/item/shops">
で飛ばして
<xsl:template match="shops">
<xsl:for-each select="shop">
<xsl:if test="contains(.,$where)">
<xsl:value-of select="../../title[not(.=preceding::title)]"/>
</xsl:if>
</xsl:for-each>
</xsl:template>

A 回答 (1件)

テストケースの作り方が悪い。

再現しないんで何がいいたいか伝わらないよ(笑)

pop-bombさんのいいたそうなことを予測します。(外れるかもしれない)
うまく行くかも自信ない
====================================
以下のようなXMLファイルを考える

#gooのシステムの都合上,well-formedじゃなくなるかもしれないけど,それはgooのせいです。(空白に良く似た文字が挿入されることが多いので
良く探してください)
#まぁわかるよね,ってことで,その時は修正してください
<?xml version="1.0" encoding="UTF-8"?>
<list>
<item>
<title>チョコレート</title>
<value>200円</value>
<shops>
<shop>○○ストア</shop>
<shop>スーパー△△</shop>
<shop>駄菓子屋□□</shop>
</shops>
</item>
<item>
<title>本</title>
<value>1000円</value>
<shops>
<shop>○○ブックス</shop>
<shop>△△百貨店</shop>
<shop>スーパー△△</shop>
<shop>スーパー××</shop>
</shops>
</item>
<item>
<title>うめぼし</title>
<value>100円</value>
<shops>
<shop>スーパー○○</shop>
<shop>△△百貨店</shop>
<shop>通販○○</shop>
</shops>
</item>
</list>

このとき,本を販売する,異なるスーパーが二つ以上存在するようにしたことに注意。
ここで,以下のXSLTを適用すると

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<data>
<xsl:apply-templates select="list/item/shops" />
</data>
</xsl:template>

<xsl:template match="shops">
<xsl:for-each select="shop">
<xsl:if test="contains(.,'スーパー')">
<li><xsl:value-of select="../../title" /></li>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

=========================

<data>
<li>チョコレート</li>
<li>本</li>
<li>本</li>
<li>うめぼし</li>
</data>

===========================
という出力結果が得られる。
($whereは面倒くさいのでリテラルで置き換えました。
また、この要素がsiblingと等しくないのが常に成り立つのは明らかなので省略。)

しかし、これは「本」が重複してしまっているので

<data>
<li>チョコレート</li>
<li>本</li>
<li>うめぼし</li>
</data>

としたい。

==========================
そこで
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<data>
<xsl:apply-templates select="list/item/shops/shop[contains(text(),'スーパー')]/../../title" />
</data>
</xsl:template>
<xsl:template match="title">
<li><xsl:value-of select="text()" /></li>
</xsl:template>
</xsl:stylesheet>

というXSLTを作成し、適用したところ,
期待する結果が得られた。
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!