- PR -

for-eachでの処理では不可能でしょうか?

1
投稿者投稿内容
IPM
会議室デビュー日: 2006/06/24
投稿数: 2
投稿日時: 2006-06-24 15:22
お世話になっております。
こちらにてご質問させて頂きたく、投稿致しました。


本店.xml
<BOOK CODE="A">
<BOOK CODE="B">
<BOOK CODE="C">
<BOOK CODE="D">

新宿店.xml
<BOOK CODE="X">
<BOOK CODE="Y">
<BOOK CODE="A">
<BOOK CODE="Z">


というXMLがあり、

本店と新宿店のCODE属性の値を比較して、新宿店にあるものは非対称とした
本店の要素を抜き出したいと考えています。

上の結果ですと、

<BOOK CODE="B">
<BOOK CODE="C">
<BOOK CODE="D">

となります。
( <BOOK CODE="A">は新宿店にあるので非対称)


本店、新宿店の属性BOOKをそれぞれfor-eachでLOOPさせ、
・もし新宿店にあればLOOP(新宿店)を抜け出す。
・新宿店の最後の要素までいって無ければ書き込む。
という記述をしたいのですが、for-eachではLOOPのexitができない様なので
新宿店にあった場合の処理の記述が出来ない状況です。

これは根本的にロジックを考え直したほうが良いのでしょうか?
〜を使ったほうが良いなどのヒントでも頂けましたら幸いです。

よろしくお願い致します。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2006-06-25 11:48
>これは根本的にロジックを考え直したほうが良いのでしょうか?

そのとおり、xslt/XPath のスタイルを身についていませんから。
サンプルソースを大量に読んで、手続き発想を 弱める必要があります。

気分はこんなモン

本店/BOOK[not(@CODE = 新宿店/BOOK/@CODE)]

3.4 ブールhttp://www.infoteria.com/jp/contents/xml-data/REC-xpath-19991116-jpn.htm#booleans
(改行無し、の中に埋まっていて読みにくいですが。)
比較するオブジェクトの1つがノード集合で
もう1つが文字列の場合は、
ノードの文字列値と比較対象の文字列を比較して、
結果が真になるようなノードがノード集合内にある場合のみ、
比較結果は真になる。
---------------------------------------------
ウソSQL風では
select BOOK
from 本店/BOOK
where @CODE != any(新宿店/BOOK/@CODE)
で、SQLのように、XPathが最適化動作するかどうか知りません。

XLinq では
データソース
|フィルター1
|フィルター2
|フィルター・・・・

とか パイプ演算子似 に、なるみたいです。


[ メッセージ編集済み 編集者: MMX 編集日時 2006-06-25 19:25 ]
IPM
会議室デビュー日: 2006/06/24
投稿数: 2
投稿日時: 2006-06-26 18:46
MMX様、大変ありがとうございました。
書き込みを参考させて頂き出来ました。

以下サンプルになります。
---
a.xml
<?xml version="1.0" encoding="Shift_JIS" ?>
<?xml-stylesheet href="c.xsl" type="text/xsl" ?>

<TEST>
<BOOK CODE="A" />
<BOOK CODE="B" />
<BOOK CODE="C" />
<BOOK CODE="D" />
</TEST>
--
b.xml
<?xml version="1.0" encoding="Shift_JIS"?>
<TEST>
<BOOK CODE="X" >あ</BOOK>
<BOOK CODE="Y" >い</BOOK>
<BOOK CODE="A" >う</BOOK>
<BOOK CODE="Z" >え</BOOK>
</TEST>
--
c.xsl
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:template match="/">
<html>
<head>
<title>test</title>
</head>
<body>
<xsl:apply-templates select="TEST/BOOK" />
</body>
</html>
</xsl:template>

<xsl:template match="BOOK">
<xsl:variable name="bdata" select="document('b.xml')" />
<xsl:if test="current()[not (@CODE = $bdata/TEST/BOOK/@CODE) ]">
<xsl:value-of select="@CODE" />
</xsl:if>
</xsl:template>

</xsl:stylesheet>

--
documentはloopさせないでもよかったんですね。
初心者の質問にお答えいただき有難うございました。m(__)m
1

スキルアップ/キャリアアップ(JOB@IT)