- ベストアンサー
ノードの並び替え方法について
- javaでDOMを使ってXMLファイルを作成していますが、ノードを並び替える方法がわかりません。
- 階層が深いとコピーが大変になるため、簡単に実現する方法はないのでしょうか?
- ご存知の方、教えていただけると助かります!
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
#5>これがXSLTで簡単に変換できてしまうなら是非ご教示ください。 エラートラップを簡略していますが、こんな感じ。 XSL の部分はオンメモリということで文字列で持っていますが、 ファイルから取り込むのももちろん可。 ---------------------------------------------------------------- import java.io.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.stream.*; import javax.xml.parsers.*; import org.w3c.dom.*; public class Sample { public static void main(String args[]) throws Exception{ String xsl= //"<?xml version='1.0' encoding='Shift_JIS' ?>"+ "<xsl:stylesheet version='1.0' "+ "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"+ "<xsl:output method='xml' version='1.0' encoding='Shift_JIS' indent='yes' />"+ "<xsl:template match='/ROOT'>"+ "<xsl:element name='ROOT'>"+ "<xsl:apply-templates select='PARENT1' />"+ "<xsl:copy-of select='PARENT2' />"+ //そのまま "<xsl:apply-templates select='PARENT3' />"+ "</xsl:element>"+ "</xsl:template>"+ "<xsl:template match='PARENT1'>"+ "<xsl:element name='PARENT1'>"+ "<xsl:copy-of select='CHILD_HEAD' />"+ "<xsl:copy-of select='CHILD_PROP' />"+ "<xsl:copy-of select='CHILD_END' />"+ "</xsl:element>"+ "</xsl:template>"+ "<xsl:template match='PARENT3'>"+ "<xsl:element name='PARENT3'>"+ "<xsl:copy-of select='CHILD_HEAD' />"+ "<xsl:copy-of select='CHILD_END' />"+ "<xsl:copy-of select='DETAILS_A' />"+ "</xsl:element>"+ "</xsl:template>"+ "</xsl:stylesheet>"; DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dbfactory.newDocumentBuilder(); Document doc = builder.parse(new File("parent.xml"));//ファイルからDOMを作る、実際は作ってあるはずなのでこの部分は必要ない DOMSource in = new DOMSource(doc); StreamSource ss = new StreamSource(new StringReader(xsl)); StreamResult out = new StreamResult(new File("result.xml")); //ファイルに書き出す TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf = tff.newTransformer(ss); tf.transform(in,out); } }
その他の回答 (5)
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>実際はそうではないです。 そうですか、また、具体的なコードを書かなくて良かったです。 次から次へと、あれは、(実際とは)違ってるとか言われると萎えるし・ #3(と#1)でできるということは、おわかりになったのでしょうか? まさに、DOM(とか)を変換するというものですけど・ XSLTがわからないとどう書いていいのかわからんかもしれませんね。 #1を見て貰うと判るかもしれませんが、 マッチしたところを、こういう構成に変更するというのが基本的なテンプレートの書き方なので、直下のノードであろうがあるまいが、 ここで、これにマッチしたものをこれに置き換えるという記述ができます。 結局実際と違うということになってしまうので、質問で書かれた構成についてサンプル(XLST)を書いてもムダになってしまうので、 もし、問題がなければ、実際のこういう構成のものをこういう構成にしたいというものを補足してもらうのが簡単だと思います。
補足
BLUEPIXYさん、こんばんは。何度もすみません。 実際の構成はノード名は違いますが以下のものになります。 (変換前) <ROOT> <PARENT1> <CHILD_PROP/> <CHILD_END/> <CHILD_HEAD/> </PARENT1> <PARENT2> <CHILD_PROP/> <CHILD_END/> </PARENT2> <PARENT3> <CHILD_END/> <DETAILS_A/> <CHILD_HEAD/> </PARENT3> </ROOT> (変換後) <ROOT> <PARENT1> <CHILD_HEAD/> <CHILD_PROP/> <CHILD_END/> </PARENT1> <PARENT2> <CHILD_PROP/> <CHILD_END/> </PARENT2> <PARENT3> <CHILD_HEAD/> <CHILD_END/> <DETAILS_A/> </PARENT3> </ROOT> このようにROOT/PARENTxx/以下のノードを、CHILD_HEAD→CHILD_PROP→CHILD_ENDの順に並び替えたいというものです。 (注意点) 1.PARENTxx以下にHEAD,PROP,ENDと3つ揃っていない場合もある。 2.CHILD_xx以下にさらにノードがある場合もある。 うーん。これでうまく伝わるでしょうか。これがXSLTで簡単に変換できてしまうなら是非ご教示ください。よろしくお願いします。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
ちょっと伺いたいのですが、 DOMツリーの中で、ルート直下のノードを入替てもあまり意味が無いような気がするのですが、 今回の目的というのは、XMLソースファイルを別の変換したXMLファイルにするということなのでしょうか?
補足
BLUEPIXYさんこんばんは(^^ 例として書いたものはルート直下ですが、実際はそうではないです。そのへんは関係ないかなと思いシンプルな例を書いてしまいました。 今回この質問をした背景としましては以下の4点です。 1.JavaコードでXMLファイルを作成する 2.すでにロジックはほぼ完成している 3.順番は関係ない→やっぱりちゃんと順番を決めると仕様が変わった(泣 4.ロジックを変えるのが大変 というわけでいったん作ったDOMツリーを簡単に並び替えられる方法を探していました。 なので「XMLソースファイルを別の変換したXMLファイルにする」ということでほぼ合っていると思います。 ※実際はXMLファイルを読み込んで変換するのではなく、何もないところから作ったDOMツリーをファイル出力する前にもう一度組み立てなおす、といった感じです。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>参考になるサイトなどありますでしょうか。 http://www.asahi-net.or.jp/~ps8a-okzk/xml/java_examples/transform.html のような感じですね。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
#1です。 >今回はソートではなく任意の並び替えが目的です。 ノード名で降順にソートしたいのだと思っていました。 >XSLは使ったことがないのですが、JAVAコードで書けるものでしょうか? TransformerFactory を使えば、XSLによる変換が可能です。 ソートとかしない単純な並び替えであれば、 XPath で指定したノードを xsl:copy-of を望む順番に置いて並び替えるだけなので、 静的なXSLでなくても、動的にXSLを作ることも簡単だと思います。
補足
BLUEPIXYさん回答ありがとうございます。 なるほど、動的に内部でXSLを作り出してそれを使うということですか。それなら外部にファイルを用意しなくても良いのでよさそうですね。 XSL自体まったく使ったことがなく、変換のやり方が想像できないのですが今回の問題でどこか参考になるサイトなどありますでしょうか。 実際のコードなど書いてあるととても助かります(^^;
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
下記のようなXSLを作成して、適用する ---------------------------------------------------------------- <?xml version="1.0" encoding="Shift_JIS"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="Shift_JIS" indent="yes" /> <xsl:template match="/PARENT"> <xsl:element name="PARENT"> <xsl:for-each select="*"> <xsl:sort select="name(.)" data-type="text" order="descending"/> <xsl:copy-of select="." /> </xsl:for-each> </xsl:element> </xsl:template> </xsl:stylesheet>
補足
すみません。XSLは使ったことがないのですが、JAVAコードで書けるものでしょうか? それと今回はソートではなく任意の並び替えが目的です。 1,2,3と単純に書いたのでソートでOKっぽく見えてしまいますね。。。(^^;)
お礼
BLUEPIXYさんこんにちは! 何度も丁寧に回答していただきありがとうございました(^^ おかげで問題も解決しました。 XSLTは今まで使ったことがなかったので、大変勉強になりました。
補足
BLUEPIXYさん。おはようございます。 ここまでソースを書いていただいてありがとうございます。 早速実際に使ってみたいと思います。 のちほど結果報告しますね。