###前提・実現したいこと
非常に複雑な構造をもったXMLファイルから必要なデータを抜き出して利用したいと思っています。
しかし、データ構造などに関する充分な資料がなく、目当てのデータがどこに含まれているかを調べるところから始めなければなりません。
目当てのキーワードは複数の異なる文脈で使用されていることがわかっています。したがって、単にそのキーワードについて検索するだけではなく、それがどのようなタグの下に書かれているかも把握しなければなりません。これをxsltとxpathを利用して簡素に実現できないかと考えました。
###発生している問題
そこで、後述のように、xsltファイルを作ってみたのですが実行結果は微妙に期待とずれております。その原因と対策をお教えいただければ嬉しく思います。xsltなんか使わなくてもこうすれば簡単だよ!的なアドバイスも大歓迎です。
###該当のソースコードとデータ
テストデータ(test.xml)
xml
1<?xml version="1.0" encoding="UTF-8"?> 2<xml> 3<node1 id="node1_1"> 4 <node2 id="node2_1"> 5 abcd 6 </node2> 7 <node2 id="node2_2"> 8 <node3 id="node3_1"> 9 xxxx 10 </node3> 11 </node2> 12</node1> 13<node1 id="node1_2"> 14 <node2 id="node2_3"> 15 cccc 16 <node3 id="node3_2"> 17 xxxx 18 </node3> 19 </node2> 20</node1> 21</xml>
某サイトの記事を参考に、"xxxx"という文字列を含むノードをリストアップすべく見よう見まねで書いてみたxsltデータ(test.xsl)
xml
1<?xml version="1.0" encoding="utf-8"?> 2<!-- https://stackoverflow.com/questions/12369734/get-all-ancestors-of-current-node --> 3<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 4 <xsl:template match="/"> 5 <xsl:variable name="curr" select="//*[contains(text(),'xxxx')]"></xsl:variable> 6 <xsl:variable name="test1" select="$curr/self::*"></xsl:variable> 7 <xsl:for-each select="$test1"> 8start 9 <xsl:value-of select="concat(name(), ': ID=', @id)"></xsl:value-of> 10 <xsl:variable name="test2" select="$test1/ancestor::*"></xsl:variable> 11 <xsl:for-each select="$test2"> 12 ancestor 13 <xsl:value-of select="concat(name(), ': ancestorID=', @id)"></xsl:value-of> 14 </xsl:for-each> 15end 16 </xsl:for-each> 17 </xsl:template> 18</xsl:stylesheet>
###試したこと
次のようにコマンドを実行してみました。
xsltproc ~/work/test.xsl ~/work/test.xml
すると、次のような結果が得られます。
<?xml version="1.0"?> start node3: ID=node3_1 ancestor xml: ancestorID= ancestor node1: ancestorID=node1_1 ancestor node2: ancestorID=node2_2 ancestor node1: ancestorID=node1_2 ancestor node2: ancestorID=node2_3 end start node3: ID=node3_2 ancestor xml: ancestorID= ancestor node1: ancestorID=node1_1 ancestor node2: ancestorID=node2_2 ancestor node1: ancestorID=node1_2 ancestor node2: ancestorID=node2_3 end
惜しいところですが、余計な兄弟のデータが一生に出力されており、これでは使えません。私としては次のような出力を期待しているのです。
<?xml version="1.0"?> start node3: ID=node3_1 ancestor xml: ancestorID= ancestor node1: ancestorID=node1_1 ancestor node2: ancestorID=node2_2 end start node3: ID=node3_2 ancestor xml: ancestorID= ancestor node1: ancestorID=node1_2 ancestor node2: ancestorID=node2_3 end
###補足情報(言語/FW/ツール等のバージョンなど)
環境:CentOS 6.6
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。