スキップしてメイン コンテンツに移動

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

エラー

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

コメント

このブログの人気の投稿

GolangでWindows GUIアプリケーション

GUIアプリ作成の前提 社内ツールとしてexeで配布 開発環境はGoLandを使う 社内ツールとしてexeを配布ということであれば、Visual StudioでC#による開発だと思います。しかしながら、Go言語を習得したいのと、GoLandの補完機能が便利で、Android Studio使っていたこともあり、とっつきやすいという点からGo縛りでGUIアプリケーションを考えたいと思います。 lxn/walk Windows application library kit for Go. Windows向けしか考えていないので、まずこのライブラリなのですが、ボタンやコンボボックスが思ったように並ばなかったり、手軽にイメージボタンを配置したりなど、簡単にレイアウトを変更できない課題に直面しました。レイアウト作成だけで時間を取られてしまいます。そう言えば、Androidアプリ開発のときは、XMLでデザイン部分を切り離してたのを思い出して、今回の調査の運びとなりました。 fyne-io/fyne Cross platform native GUIs designed for Go based on Material Design. Supports: Linux, macOS, Windows, BSD, iOS and Android. walkと比べると、クロスプラットフォームで作成できるのですが、こちらもコードの中にデザインを書いていく形でした。 therecipe/qt therecipe/qt allows you to write Qt applications entirely in Go or JavaScript. Qt Creatorなるものがあるようで、デザイン部分を切り離せる印象はあるものの、最新のPCでもビルドに時間がかかるようで、学習コストもかかるという記事を見かけて断念しました。 どうしたものかとツイートしましたら、下記のようにご助言をいただいた。 同じ課題に対し色々試した結果、PWAのフルキャッシュドに落ち着いた。中身はGo+WASMで。 https://t.co/e60whDTV16 — のぼのぼ📡 (@nobonobo) July 21, 2020 PWA 早速調べてみました。Googleが進めているプロジェクトで、ネイティブアプリのよ

Eclipseで一通り基本的なGitを使ってみる

備忘録的にまとめておきたいと思います。おかしな点があればご指摘いただければ幸いです。 目次 環境 プロジェクト作成~初コミットまで コミットの履歴&差分を見る 元に戻す ブランチについて ブランチを作成してみる ブランチを統合するには マージする Rebaseする ローカルリポジトリからプロジェクトを取り込む コミットしたメッセージの修正 環境 Eclipse IDE for Java Developers:Juno Service Release 1 Git:上記Eclipseのプリインストール版

Javaでprivateなfieldやmethodにアクセスする

JUnitでテストしてると、privateなフィールドにアクセスして、値を参照したりセットしたりしたくなるわけですが、よく使うのでメモしておきます。 例えば、次のような対象のクラスがあるとします。 public class ParentClass { private String hoge = "ParentClass!!"; public void dispMsg() { System.out.println("dispMsg:" + hoge); } private void privateDispMsg(String msg) { System.out.println("dispMsg:" + msg); } }