- - PR -
xsltにおいて子ノードのマッチングで親ノードの結合方式
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2006-05-30 18:01
root
以下のようなxmlがあります。 ┣親ノード1 ┃┣子ノード1 ┃┣子ノード2 ┃┗子ノード3 ┣親ノード2 ┃┣子ノード1 ┃┣子ノード2 ┃┗子ノード4 ┗親ノード3 ┣子ノード1 ┣子ノード2 ┗子ノード4 親ノード1/子ノード1 = 親ノード2/子ノード1 かつ 親ノード1/子ノード2 = 親ノード2/子ノード2 のとき ┣親ノード1 ┃┣子ノード1 ┃┣子ノード2 ┃┣子ノード3 ┃┗子ノード4 ┗親ノード3 ┣子ノード1 ┣子ノード2 ┗子ノード4 ということを行いたいのです。 ただしxmlを作る必要は無く、Webに表示(htmlが出れば)できればよいのですが 何とかならないものでしょうか? 子ノード1、子ノード2でソートすれば今一歩というところまで いくのですが、後一歩が踏み出せません。 お知恵をお貸しください。 |
|
投稿日時: 2006-05-31 10:49
検索語 は XSLT 集約
要素の集約(2) http://qa.xml.gr.jp/data/xsl/files/0048.xml XPath2.0 の distinct データ用のXML: XPath 2.0の新機能 http://www-06.ibm.com/jp/developerworks/xml/021206/j_x-xdxpath2.html ↑ 古いかも、こんな感じ、 データ型、名前空間と がっぷり四つ なので、難産。 |
|
投稿日時: 2006-05-31 12:01
助かりました。
絶対できるだろうと思っていたのですが、 なかなか探せないで苦労していたところです。 お礼だけでは、なんですので私のほうもひとつ裏技を。 Microsoft.XMLDOM + XSLT + javascriptで reslst.innerHTML = objDoc.transformNode(objXSLT); こんなことやりますよね。 これが、 document.write(objDoc.transformNode(objXSLT)); とできます。(当たり前?) もう一歩進んで var fso = new ActiveXObject("Scripting.FileSystemObject"); var a = fso.CreateTextFile("c:\\testfileS.txt", true); a.Write(objDoc.transformNode(objXSLT)); なんてこともできちゃいます。(マイクロソフト恐るべし、これってトロイの・・・) |
|
投稿日時: 2006-06-01 11:21
う〜ん、いまいちだな。
http://qa.xml.gr.jp/data/xsl/files/0048.xml を多少作り変え、 2つのノードをマッチングさせるとき、 <xsl:for-each select="record[((not(id = preceding-sibling::record/id))or(not(data = preceding-sibling::record/data)))]"> でその数だけは検出してくれるのですが、 <xsl:for-each select="key('id', id)">と <xsl:for-each select="key('data', data)">の 組み合わせ方がわかりませんね。 考え方としては、id とdataのどちらかが異なるものを行変えの対象とし、 idとdataがまったく同じものを、その行に追加していくと考えているのですが いまひとつ得たいものがしっくり来ません。 id とdata を一組としてキーにできればうまく行くのでしょうが、 規約を読んでも理解力の無さに参っています。 以下ソース -----(test.xml) <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="test2.xsl"?> <database> <record> <id>#1</id> <data>a</data> <aaa>1</aaa> </record> <record> <id>#1</id> <data>a</data> <bbb>8</bbb> </record> <record> <id>#1</id> <data>b</data> <aaa>2</aaa> </record> <record> <id>#1</id> <data>b</data> <bbb>2</bbb> </record> <record> <id>#2</id> <data>c</data> <aaa>2</aaa> </record> <record> <id>#2</id> <data>c</data> <bbb>5</bbb> </record> <record> <id>#3</id> <data>d</data> <aaa>2</aaa> </record> <record> <id>#3</id> <data>d</data> <bbb>8</bbb> </record> <record> <id>#4</id> <data>d</data> <aaa>2</aaa> </record> <record> <id>#4</id> <data>d</data> <bbb>10</bbb> </record> </database> ---test2.xsl <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:key name="id1" match="record" use="id" /> <xsl:key name="data1" match="record" use="data" /> <xsl:output method="html" encoding="Shift_JIS" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="database"> <TABLE BORDER="1"> <TR> <TD>ID</TD> <TD>data</TD> <TD>aaa</TD> <TD>bbb</TD> </TR> <xsl:for-each select="record[((not(id = preceding-sibling::record/id))or(not(data = preceding-sibling::record/data)))]"> <xsl:if test="aaa"> <TR> <TD><xsl:value-of select="id"/></TD> <TD><xsl:value-of select="data"/></TD> <TD><xsl:value-of select="aaa"/></TD> <xsl:for-each select="key('data1', data)"> <xsl:if test="bbb"> <TD><xsl:value-of select="bbb"/></TD> </xsl:if> </xsl:for-each> </TR> </xsl:if> </xsl:for-each> </TABLE> </xsl:template> </xsl:stylesheet> |
|
投稿日時: 2006-06-02 05:59
id+dataでひとつのノードを新規に作成した中間ファイルを作って
解決しました。 しかし、時間に追われていたとはいえ、情けない。 |
|
投稿日時: 2006-06-02 13:52
仕様を読んでおくと、ギリギリの粘りがつきます、犠牲者と生還者の違い。
<!-- Category: top-level-element --> <xsl:key name = qname match = pattern use = expression /> use は 単項ではなく、式を書ける。concat(id,data) とか、 中間ファイルを作るのは、けっこう 武勇伝、武勇伝。 [ メッセージ編集済み 編集者: MMX 編集日時 2006-06-04 10:16 ] |
|
投稿日時: 2006-06-05 11:09
あっちゃんかっこいい(w
ただ、10万件ほどのXMLで行ったら時間のボトルネックに引っかかりました。 処理時間の問題はつらい。 やっぱりDBに入れることを考えます。 しかしWebを立てず、フリーソフトの範囲で、IEのセキュリティレベル高でという要求を 受けた私が馬鹿だった。 虐めとしか思えない要求じゃ・・・・ |
|
投稿日時: 2006-06-05 11:30
Office 2007 ベータ は 期間限定の フリー かも
OpenOffice2.0 の Base もDBですが。 参考 HTA(JavaScript) で作るのなら Revight エディタ あたりが限界点。 |