Android、Java、Web系、Linux、マラソン等の備忘録

2012/10/26

Android:Documentでparseしたものを文字列に戻したい

0 件のコメント

エラー

java.lang.NoClassDefFoundError: org.apache.xalan.processor.TransformerFactoryImpl

経緯

AndroidでEvernoteのクラウドAPIを使ってノートの本文(XML)を解析するにあたり、調べてみたら、SAXだとかいろいろあるみたいですが、org.w3c.domがノードをたどれるし、今まで使った事のある経験から採用しました。

※まぁparseが遅いとかいうのもチラっと見かけましたが、次の記事あたりに遅さを解消について書きたいと思います。大したことではありませんが。

で、parseしてデータを取得するまではいいんですけど、これをEvernoteのnoteとして反映させるためには、paerseしたものをまた文字列へ戻す必要があります。ググるとTransformerが使われている例が多かったので、試してみました。Javaで動いてるJUnitで動かしてみたら問題なさそうだったのですが、Androidで動かしたら上記のエラーが出てしまいました。

対応

parseできるなら戻せるようにしておいて欲しい所ですが....どうするかについては単純に3種類くらいでしょうか。
  • それでもTransformerを使うべくxlan.jarを導入する
  • 他のフレームワークを使う
  • 手動で解析
xalan.jarを入れるが楽ではあるんですけど、
ただでさえ、EvernoteのクラウドAPIとActionbarSherlockの導入で数MBに肥大しているので、たかだか文字列にしたいだけで1.7MB近くあるJARファイルを入れたくないですし、
・java.lang.NoClassDefFoundError: org/apache/xalan/processor/TransformerFactoryImpl - Simple difficult things in Java, J2EE, J...
http://simpledevelopment.weebly.com/2/post/2011/11/javalangnoclassdeffounderror-orgapachexalanprocessortransformerfactoryimpl.html
バッドソリューションなどと書かれてますし....

他のフレームワークは特に調べてはないですが、容量増やしたくないということで、手動でやろうかなと。でも、完全に自分でやるのはデバッグが大変そうなのでググったらこちらの下の方にあるDmitryさんが紹介されてるやり方がいいんじゃないかと。
・Writing XML on Android - Stack Overflow
http://stackoverflow.com/questions/2290945/writing-xml-on-android
先頭にxmlタグ付けてくれたり、空白が多かったりするので除去したものを載せておきます。

※注意:追記参照


    private static String getStringFromNode(Node root) throws IOException {

        StringBuilder result = new StringBuilder();

        if (root.getNodeType() == 3)
            result.append(root.getNodeValue());
        else {
            if (root.getNodeType() != 9) {
                StringBuffer attrs = new StringBuffer();
                for (int k = 0; k < root.getAttributes().getLength(); ++k) {
                    attrs.append(" ").append(
                            root.getAttributes().item(k).getNodeName()).append(
                            "=\"").append(
                            root.getAttributes().item(k).getNodeValue())
                            .append("\"");
                }
                result.append("<").append(root.getNodeName()).append("")
                        .append(attrs).append(">");
            }

            NodeList nodes = root.getChildNodes();
            for (int i = 0, j = nodes.getLength(); i < j; i++) {
                Node node = nodes.item(i);
                result.append(getStringFromNode(node));
            }

            if (root.getNodeType() != 9) {
                result.append("</").append(root.getNodeName()).append(">");
            }
        }

        return result.toString();
    }

パラメータがnodeですが、Documentのオブジェクトを突っ込んでやれば文字列を戻してくれます。

追記:2013/02/24 ---------
このサンプルソースは、セルフクロージングタグであっても、それを解いて通常のクロージングタグにしてしまうので注意が必要です。シンプルで良いのですが、安易に使うと危険な気がします。
原形をとどめて戻すやり方は調べたいですが、保留中です.....

0 件のコメント :

コメントを投稿