[ruby] [java] [favarite]

XMLについてのメモ(書き直し中)

SGMLにも携わってたおかげで、XMLはずいぶんすっきりと整理されているように思えるけど結構覚えなくちゃいけないばかり。日々勉強中です。

ツール類もSGMLの頃と比較して「色々ありすぎ」で、どれを使うか考えるだけでも悩みます。

メモしておいて役立ちそうな情報を用意してみました。


XMLのパース

パースとは、XMLデータが正しいデータであることを検証することです。

XMLデータが正しいものであるということは、「ウェルフォームであること」か「ウェルフォームであり、かつDTDの決まりごとにのっとっている」のどちらかであることを指します。
パーサの種類によって、「ウェルフォームドのみチェック(non-validating)」と「DTDとの整合性もチェック(validating)」を指定することができます。

次のようなパーサがあります。

Project X

Sun Microsystemsが開発したJava用XMLパーサです。JDK1.4からは標準でこのProject Xが同梱されるそうです。(Java Press Vol.13によると、Project XのApacheへの提供部分の成果がcrimsonとしてリリースされているそうです。某プログレッシブロックバンドと同じですね。Project XCrimson)

XML4J

IBMが開発したJava用XMLパーサです。XML用パーサとしては老舗です。最新のはApache XML Projectと合体してXercesになっています。SunのProject Xが登場するまではJava XMLパーサと言ったら、ほとんどこれを指していたでしょう。

Ruby XMLParser

オブジェクト指向スクリプト言語Rubyには、expatというC言語で作成されたXMLパーサの機能を取り込むためのライブラリXMLParserが用意されています。使うには、XMLParserのソースと共にexpatのソースも必要です。蛇足ですが、Perlにも同様のものがあります。

XMLをブラウザで表示する(XSLT)

工事中.....


XMLプログラミング

RubyによるXMLプログラミング

ruby1.6.1でexpat、xmlparser、uconvをコンパイル、インストールした後、サンプルスクリプトを実行すると、
/usr/local/lib/ruby/site_ruby/1.6/xmlparser.rb:5:in `require': libexpat.so.0: cannot open shared object file: No such file or directory - /usr/local/lib/ruby/site_ruby/1.6/i686-linux/xmlparser.so (LoadError)
というエラーメッセージが表示されました。ライブラリが見つからないので、きちんと認識させるため、次の方法で以下を回避。

サンプル

特定のノード内の中身を取り出す、特定のノード数を数えるサンプルスクリプト。
#! /usr/local/bin/ruby

require 'xmltreebuilder-ja'
require 'nkf'
require 'uconv'
require 'kconv'

include XML::SimpleTree

class ManipulateXML

  def initialize(f)
    ### ソースファイル(XML)の読み込み
    builder = XML::JapaneseTreeBuilder.new(1)
    begin
      # パース
      xmltree = builder.parseStream(f)
      root = xmltree.documentElement # Rootエレメントの取得
      @nodes = root.childNodes        # Rootエレメントの子ノードの取得
      #return xmltree

    rescue XMLParserError
      # エラーの例外処理
      line = builder.line
      print "#{$0}: #{$!} (in line #{line})\n"
      exit 1
    end

  end

  def getSpecificNodeValue(s) # ノード内の任意のタグの内容を取得
    return _getSpecificNodeValue(@nodes, s)

  end

  def _getSpecificNodeValue(nl, s)
    str = ""
    nl.each do |e|
      if e.nodeType == 1 # タグノードの場合
 if e.nodeName == s
   str += "[[ " + e.childNodes.to_s + " ]]\n" 
 end
      end

      if e.hasChildNodes
 str += _getSpecificNodeValue(e.childNodes, s)
      end 
    end
    return str
  end

  def countNodes(s) # ノード内の子レベルの任意のタグの数を取得
    return _countNodes(@nodes, s, 0)
  end

  def _countNodes(nl, s, count)
    count = 0
    nl.each do |e|
      if e.nodeType == 1 # タグノードの場合
 # 目的のノードならカウントする
 count += 1 if e.nodeName == s
      end
      if e.hasChildNodes
 count += _countNodes(e.childNodes, s, count)
      end
    end
    return count
  end

end

# test
mx = ManipulateXML.new($<)

# 特定のタグの中身を表示するサンプル
print "<title>の中身は", mx.getSpecificNodeValue("title"), "です.\n"

# 特定のタグの個数を表示するサンプル
print "<p>は", mx.countNodes("p"), "個ありました.\n"

DelphiによるXMLプログラミング

DelphiでXMLといっても、MicrosoftのMSXML.DLLをタイプライブラリ化して使うという悲しい現実です。エンタープライズ版にはDelphiのXMLライブラリとかあったような気がした。

ここではDelphi5でMSXMLをタイプライブラリした時の手順と簡単なサンプルを紹介します。

  1. [コンポーネント]メニューの[パレットの設定]からMSXML用に新しいページを追加
  2. [プロジェクト]の[タイプライブラリの取込]を選択
  3. msxmlを選択
  4. [インストール]をクリック
  5. [インストール]ダイアログが表示されるが、特に問題なければ[OK]をクリック
新規に作成したパレットのページ内にコントロールのアイコンが追加されます。

XercesをDelphiで使う

VBを使わずDelphiを使っているユーザは、どこかにMSなんか...という感情もあるのではないでしょうか?XMLプログラミングに仕方なくMSXMLなんか使っているが、本当は使いたくないとか。

それでは、他にDelphiで使えるXMLパーサがあるのか?色々見てたら、ちょうどXercesのCOM版があることがわかりました。

さっそくダウンロードして使ってみることにしました。

Delphiからの使い方はMSXMLの場合と同様、タイプライブラリ化してから使います。実際のコーディングはMSXMLの場合と同じです。


その他つれづれなるままに

Relax

SmartDoc


参考文献・リンク



Vrooom

Last modified: Mon Jan 15 12:00:00 JST 2001