- PR -

XMLの子ども要素を丸ごとStringで取得する方法

1
投稿者投稿内容
あすか
ぬし
会議室デビュー日: 2006/07/12
投稿数: 309
投稿日時: 2007-07-19 15:27
お世話になっております。

XMLファイルを読込む勉強中です。
行き詰ってしまったのでお知恵を拝借させてください。


下記のようなXMLが用意されています。
<ROOT>
<B id="1">s1<C/>s2<C/></B>
<B id="2"><C/>sss<C/>s<C/></B>
</ROOT>

目的は<B/>の中に<C/>がいくつあるかを数える
という物ですが、その際に<B>〜</B>の中身を
デバッグ出力して答え合わせをしようと思いました。

コンソールへの予定出力イメージ
id = 1 / c = 2
debug : s1<C/>s2<C/>
id = 2 / c = 3
debug : <C/>sss<C/>s<C/>

が、しかし、いろいろ試みて見たのですが
XMLから<B>〜</B>の間にある文字列<C/><C/>を取得する方法を
見つけることが出来ません。
<B id="1">s1<C/>s2<C/></B>ではなく<B id="1">CC</B>ならば
Node#getFirstChild()#getNodeValue()で取得可能なのですが
ノードの値にタグが含まれると取得はできないようです。
(Node#getFirstChild()#getNodeValue()だとs1のみを取得する)


現在の環境はJDK1.4.2_8、XMLの解析にはDOMを用いています。

何かご存知のことがありましたらよろしくお願いします。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-07-19 16:36
Element.getTextContent()はTEXT_NODEとCDATA_SECTION_NODEの
文字列のみを返すようです。子要素も独立した要素として扱われるので、
TextContentには含まれなくとも(分類されなくても)自然でしょう。

また、ELEMENT_NODEは元々のXML上での表現では保持されないようです。
<C />のように、要素中に追加した空白はLSSerializer(JavaSE 5以降)で
出力しても復元できませんでした。

#もしかしたら細かいオプション指定で出来るかもしれません。
sawat
大ベテラン
会議室デビュー日: 2006/08/02
投稿数: 112
投稿日時: 2007-07-19 18:07
XSLのjavax.xml.transform.Transformerを使えば、DOMノードをStringにすることができます。

コード:
/** Node→String変換 */
public static String convertToString(Node node)
       throws TransformerException{

   DOMSource source = new DOMSource( node );
   StringWriter swriter = new StringWriter();
   StreamResult result = new StreamResult( swriter );
   transform( source, result);
   return swriter.toString();
}
private static void transform(Source source, Result result)
        throws TransformerException{

   TransformerFactory tff = TransformerFactory.newInstance();
   Transformer tf = tff.newTransformer();
   tf.transform( source, result );
}

あすか
ぬし
会議室デビュー日: 2006/07/12
投稿数: 309
投稿日時: 2007-07-20 09:32
Transformはこういうときにも使えたんですね。
コード:
  // 呼び出し元
  {
    StringBuffer text = new StringBuffer();
    NodeList nList = element.getChildNodes();
    for (int j = 0; j < nList.getLength(); j++) {
      text.append(convertToString(nList.item(j)));
    }
  }

  /**
   * ノードの要素値を文字列に変換します。
   * ノード内にタグが含まれている場合、そのタグは自動整形されます。
   * 
   * @param node 変換対象の文字列
   * @return 変換後文字列
   * @throws TransformerException XML規約に違反している場合に発生する例外
   */
  public static String convertToString(Node node) throws TransformerException {
    // ノードをXMLとして定義します
    DOMSource source = new DOMSource(node);
    // 文字列生成用ストリーム
    StringWriter swriter = new StringWriter();
    StreamResult result = new StreamResult(swriter);
    // XMLを文字列に変換します
    transform(source, result);
    return swriter.toString();
  }

  /**
   * XML変換エンジン呼び出しです。
   * 
   * @param source 変換対象のXML
   * @param result 変換後文字列
   * @throws TransformerException XML規約に違反している場合に発生する例外
   */
  private static void transform(Source source, Result result) throws TransformerException {
    // 変換エンジンを取得します
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    // XML変換のルールを設定します
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    // 変換
    transformer.transform(source, result);
  }



最終的に上記のようにして望む文字列に変換できました
ありがとうございます
1

スキルアップ/キャリアアップ(JOB@IT)