年別アーカイブ: 2015年

40件の投稿

平将門

私は広島で育ち、大学を卒業して大阪のゼネコン設計部で建築家を目指して働いていました。

会社の寮は芦屋の近くでしたので、関西にいることの利点を生かさない手はないと、休みになれば、電車やバスを乗り継いで、奈良に出かけて、日本建築の勉強のため古建築を見て回りました。

奈良を卒業して、そろそろ京都に行こうと思っていたとき、東京の某大学の大学院に行く決心をして、会社を1年足らずでやめましたので、結局、京都にはあまり行きませんでしたが、それにしても、奈良もまだまだ行きたいところは沢山残っていたし、それに比べて東京に来てみると、「なんと歴史の薄いところだ。何も見るものがない」と東京の歴史の浅薄さに失望したものです。

そんなわけで、関東に住んでいても、関東の歴史に関心がないままに、長い間東京周辺で生活してきました。

しかし、それにしても関東についてあまりにも知識がないと反省し、すこし身の回りの歴史を勉強しようと気持ちを変えました。

関東で最も有名な歴史上の人物の一人は平将門です。
それに、将門は私のご近所で活躍した人物です
それなのに将門のことは何も知りません。

童門冬二「小説 平将門」(集英社 2002年)を読みました。

Yahooの地図で確認しながら、「ここで誰々と戦った」と、1000年以上前の事件を興味深く辿りました。

時は平安京の時代(西暦930年代)で、都の政治は藤原氏が牛耳っていました。

天皇家もすでに60代を数え、天皇の末裔は沢山いた訳で、これらの人が全員貴族として、宮中で安穏な生活をしていたわけではありません。皇族の血を引くといえども、それぞれ独力で生活の糧を得なければいけません。

天皇の嫡出の男子およびその皇孫は親王とよばれ、それ以外の皇孫は単に王と呼ばれました。

親王は天皇直轄地の長官・守(かみ)の役職につきますが、彼らは実際には現地にはいかず、京都でぬくぬくと生活しています。

その穴を埋めるべく現地にいくのは、次官の位・介(すけ)をもらった王たちです。しかし、それさえもありつけない皇孫は、朝廷で実権をほしいままにする藤原家に恨みつらみを募らせます。

将門の先祖・高望王も上総介として関東に派遣され、将門の時代には、すでに土着の豪族と婚姻関係を結び、根を張った生活基盤を構築していました。

将門には叔父が沢山おり、大体は筑波山の西の肥沃な土地に居を構えていました。

従弟の貞盛は、京都で役職を得て、中央政権での出世を夢見ています。将門も京都で端役をもらい、実直に働いていました。

そんな中、将門の父良将が死去します。

良将が支配していたのは、筑波から西に外れた今の岩井や猿島、菅沼あたりの土地で、しばしば鬼怒川の氾濫に見舞われ(昨日集中豪雨で決壊したのもこの辺りです)、多数の小河川が縫う湿地が多い、稲作には適さないところです。

将門は、上司である摂政関白藤原忠平に暇乞いをし、筑波の地に帰ってみると、父の土地は既に叔父たちが占拠していました。

これが約10年に及ぶ大事件の発端です(と著者はいっています)。

将門は母の実家、今の茨城県取手市(関東鉄道常総線、新取手のあたり)にひとまず落ち着き、忠平から御厨の下司(下級役人)というポストを任命されていたので、間もなく、弟達と今の坂東市岩井と鬼怒川と小貝川に挟まれた常総線宗道近くに屋敷を構え、馬の改良・生産に力を注ぎます。

小説によると、将門は形式にとらわれない人間だったので、朝鮮半島から亡命してきた人や、中央政権から差別されていた蝦夷とも平気で付き合い、多くのことを学びます。

特に高麗人からは日本では見たことのない素晴らしい高麗馬を分けてもらい、騎馬による戦闘・戦術を教わります。高麗は朝鮮半島の北・高知を拠点にしていたので、騎馬戦を得意としていたのです。

叔父たちとの反目はやがて戦闘になり、しかし騎馬戦に長けた将門は、叔父たちとの数度の局地戦に勝利し、その結果、叔父一族は次々に戦死します。

当然叔父たちの憎しみは増し、泥沼の戦闘を続けることになります。

小説では、将門と貞盛は友人として、信頼していましたが、度重なる戦闘で、お互いに友情に決別します。

将門が武勇をとどろかせると、有象無象が寄ってきます。

一人は落ちぶれ貴族の興世王(おきよおう)です。興世王は武蔵国権守(ごんのかみー国守の補佐役)に任命されます。当時武蔵国国守は欠員になっていて、それをいいことに興世王は正式国守が着任する前に、私腹を肥やそうと勝手な行動をし、悪評が立った人物です。

興世王は藤原政治に反発して、東国に皇国を作ろうと企んでいました。

更に盗賊藤原玄明も近づき、収拾のつかない集団になっていきます。

これまでの騒乱は、あくまでも私的な闘争でしたが、やがて常陸や下野の国の役所を襲撃し、国印と鍵を奪うに至って、何かと将門をかばってきた摂政忠平も、遂に将門謀反と認定し、討伐の号令を出します。

謀反人と認定された将門は、興世王等に載せられて、京の天皇に対峙して東の親皇を名乗ります。

小説では、将門は決して中央政権に反抗するのではなく、あくまでも中央政権の枠組みの中でユートピア作りを目指したのだったが、一方の興世王にしてみれば、藤原に牛耳られた京都に対抗した王政復古の新政権設立を目指した、ということです。私には本当のところはわかりません。

さて、ときあたかも、瀬戸内海では藤原純友が乱を起こし、朝廷は将門討伐に中々力を尽くせない中、貞盛と下野の役人藤原秀郷(田原藤太)は連合で、将門に立ち向かい、(小説では)貞盛と秀郷が同時に放った矢が、将門の眉間に命中し、将門は即死します。

戦死した場所は、岩井の北、駒跳(こまはね)あたりと言われています。
将門享年38歳ということです。

将門は、東国では人気があったようです。
私の推測ですが、将門の性格が人々を魅了したのがベースでしょうが、京都公家政権に差別された東国武士のなにくそという気分もあったと思います。将門は神田明神に祀られて、戦国・江戸の武将は戦勝祈願にここを訪れたと伝えられています。
神田明神は江戸っ子には掛け替えのない神社でした。

しかし、幕末水戸の大日本史で、将門は天皇に弓引いた朝敵と断罪され、それ以降、日本3大極悪人の一人にされたということです。

なお、成田山新勝寺は、朝廷が将門征伐を祈願して建立したことから、神田明神と成田山新勝寺を両方お参りすると、将門のたたりがあると言い伝えられています。

小説は、朴とつ純朴な将門が、彼の意思に反して、事件の首謀者になってしまったと同情的に書いています。

時間をみつけて、つわものどもの夢の跡を辿ってみたいと思います。

XLSTを使って整形

取り敢えず下のURLをクリックしてください。

https://hi-kaka.com/tmp/chibaTenki.xml

前回ご紹介した、気象庁のデータをダウンロードし、下に示すXSLTファイルを関連づけました。ブラウザはchibaTenki.xmlファイルをXSLTで整形して表示しています。

chibaTenki.xmlの修正は、2行目に次の文を追加しただけです。

<?xml-stylesheet type=”text/xsl” href=”./chibaTenki.xslt”?>

ブラウザだけでなく、大抵の言語、Php、Java、Javascript、Perl、.NETで、XMLをXLST変換して新たなXMLを作成することができます。

ここで、chibaTenki.xsltが問題のXSLTファイルです。

久しぶりに手探りでXSLTを作成したし、決して立派なものではありません。XSLTをご存知ない方に、「XSLTとはこんなものです」というくらいのサンプルです。

コードを簡単にご説明します。

<xsl:template match=”/weatherforecast/pref”>(8行目)では、XMLドキュメントの”/weatherforecast/pref”タグを探して、あったらprefタグの処理をします。

ここでしていることは、出力をHTMLタグで囲んで(9行目から16行目)、HTMLファイルのタイトルを「千葉県の天気」とし、出力bodyタグの中、<xsl:apply-templates select=”area”/>(14行目)で、「以下は<xsl:template match=”area”>に任せる」としています。

制御は<xsl:template match=”area”>(18行目)に移り、18から31行目の中でareaタグの処理をします。

続いて制御が<xsl:template match=”info”>(33行目)に移り、必要な処理をした後に、<xsl:call-template name=”RAIN”/>(58行目)でサブルーチン・テンプレートをコール、<xsl:template name=”RAIN”>(61行目)の中で、rainfallchanceタグの処理をします。

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="html" indent="yes"/>
 <xsl:variable name="prefecture" select="/weatherforecast/pref/@id"/>
 <xsl:template match="/weatherforecast/title|link|description|pubDate|author|managingEditor|">
  <xsl:text/>
 </xsl:template>
 <xsl:template match="/weatherforecast/pref">
  <html>
   <head>
    <title>千葉県の天気</title>
   </head>
   <body>
    <xsl:apply-templates select="area"/>
   </body>
  </html>
 </xsl:template>
 <xsl:template match="area">
  <table border="1" width="700">
   <tbody>
    <tr>
     <th>
      <xsl:value-of select="$prefecture"/>
      <xsl:text>   </xsl:text>
      <xsl:value-of select="@id"/>
      <xsl:apply-templates select="info" />
     </th>
    </tr>
   </tbody>
  </table>
 </xsl:template>
 
 <xsl:template match="info">
  <tr>
   <th>日時 <xsl:value-of select="@date"/>
   </th>
  </tr>
  <tr>   <td/>
   <td>
    <xsl:value-of select="weather"/>
   </td>
  </tr>
  <tr>   <td/>
   <td>    <xsl:value-of select="weather_detail"/>
   </td>
  </tr>
  <tr>   <td/>
   <td>    <table>     <tbody>
      <tr>       <td>        <xsl:text>気温  </xsl:text>       </td>
       <td>
        <xsl:value-of select="temperature/range[@centigrade='min']"/>
        <xsl:text> から </xsl:text>
        <xsl:value-of select="temperature/range[@centigrade='max']"/>
       </td>      
    </tr>
   </tbody>    </table>   </td>
  </tr>
  <xsl:call-template name="RAIN"/>
 </xsl:template>
 
 <xsl:template name="RAIN">
  <tr>   <td/>
   <td>    
  <table>     <tbody>
      <tr>       <td>
        <xsl:text>降水率  </xsl:text>
       </td>      </tr>
      <xsl:call-template name="RAINBYHOUR"/>
    </tbody>    </table>
   </td>  </tr>
 </xsl:template>
 <xsl:template name="RAINBYHOUR">
  <xsl:for-each select="rainfallchance/period">
   <xsl:sort select="@hour"/>
   <tr>    <td>
     <xsl:text>  </xsl:text>
     <xsl:value-of select="@hour"/>
     <xsl:text>  </xsl:text>
     <xsl:value-of select="."/>
     <xsl:text> % </xsl:text>
    </td>   </tr>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

余談ですが、私は10年以上前に[XML Spy]というソフトを購入しました。
「使用権は永久」ということで安心していたのですが、今回これを引っ張り出して使おうとするとうまくいきません。

Altova社にメールしたら、私のライセンスは一度更新していて、最新の(といっても10年前の)ライセンス番号を送ってくれました。

というわけで、今回[XML Spy 2004]を使ってXLSTファイルを作成しました。

そんな訳で、上のXSLTファイルの2行目にstylesheet を宣言していますが、最新のXSLT2.0では、このstylesheet文を使わないことが推奨されているようです。

ここ数回に亘って、XMLについて少し整理しました。
XML処理の話はこれでおしまいです。

C#.NET XmlTextReader

前回のSAXと同じ仕事をする、XmlTextReaderを使ったコードをご紹介します。言語はC#、クラスの主要部分だけを抜き出しました。

  class MyXmlReader
  {

    private List<Area> o_lstArea = new List<Area>();

    public void XmlRead()
    {
      Area o_Area = null;
      Area.Info_data o_Info = null;

      Stack<String> elmNameStack = new Stack<String>();

      int rangCnt = 0;
      int periodCnt = 0;

      using (XmlReader reader = XmlTextReader.Create("http://www.drk7.jp/weather/xml/12.xml";))
      {
        while (reader.Read())
        {
          switch (reader.NodeType)
          {
            case XmlNodeType.Element:
              switch (reader.Name)
              {
                case "area":
                  o_Area = new Area();
                  o_Area.AreaName = reader.GetAttribute("id");

                  o_lstArea.Add(o_Area);
                  break;
                case "info":
                  o_Info = o_Area.makeInfo();
                  o_Info.Dt = reader.GetAttribute("date");
                  break;
                case "temperature":
                  rangCnt = 0;
                  break;
                case "rainfallchance":
                  periodCnt = 0;
                  break;
              }
              elmNameStack.Push(reader.Name);
              break;
            case XmlNodeType.Text:
              string elmName = elmNameStack.Pop();
              elmNameStack.Push(elmName);
              switch (elmName)
              {
                case "weather":
                  o_Info.Weather = reader.Value;
                  break;
                case "weather_detail":
                  o_Info.Weather_detail = reader.Value;
                  break;
                case "wave":
                  o_Info.Wave = reader.Value;
                  break;
                case "range":
                  o_Info.Range[rangCnt++] = Convert.ToInt32(reader.Value);
                  break;
                case "period":
                  o_Info.Rainfall[periodCnt++] = Convert.ToInt32(reader.Value);
                  break;
              }
              break;
            case XmlNodeType.EndElement:
              elmNameStack.Pop();
              break;
            }
          }
        }
      }

      public List<Area> getWeather()
      {
        return o_lstArea;
      }
    }
  }

前回と同じAreaクラスを使っていますし、やることもSAXと同じようなことをしています。

しかし、このクラスは何かのクラスを「継承していない」で、
XmlReaderを使っているだけです。

またSAXとXmlReaderの動作には大きな違いがあります。

SAXはElement(タグ)に「入った」と「出た」に対してイベントが発生するのにに対して、XmlReaderは、「Elementに入った」とか、「Textに入った」とか(他に沢山フラグが用意されています)、入った内容を知らせてきます(Elementから出たというフラグもあります)。

そして、気を付けてなければならないことはXmlReaderが読み込んで、「あ、要素だった」とか「あ、要素の内容(Text)だったか」とか分かるのですが、内容だったとき「何(タグ)の」内容なのかわからないのです。

そのために、Stackを使いました。

要素Elementに入った時に、要素名=タグ名をスタックにプッシュし、Elementから出るときにポップしています。

要素の内容(Text)が見つかった時に、スタックの一番上のタグ名を取り出し、タグ名を確認し、またプッシュしておきます。

そのほかは、前回のSAXと同じです。

XmlReaderはXMLドキュメントの特定の要素を直接読みに行く機能があるようで、もっと様々な使い方ができるのでしょうが、今の関心事は、これでおしまいです。

少なくとも、SAXの訳の分からないcharactersメソッドがないだけ、XmlReaderの方が気分的にはいいです。

Java SAX

初めてSAXを勉強したのでご紹介します。

例として、気象庁が提供している天気予報を使います。以下のURLをクリックしてください。向こう1週間の気象情報がXML形式で表示されます(下で表示されるのは、千葉県の情報です)。

http://www.drk7.jp/weather/xml/12.xml

一部をコピーします。

<weatherforecast>
<pref id="千葉県">
 <area id="北東部">
    <geo>
        <long>140.6877</long>
        <lat>35.7765</lat>
    </geo>
    <info date="2015/08/22">
        <weather>くもり</weather>
        <img>http://www.drk7.jp/MT/images/MTWeather/200.gif</img>
        <weather_detail>南の風 海上 では 南の風 やや強く 晴れ 夕方 から くもり</weather_detail>
        <wave>波 4メートル うねり を伴う</wave>
        <temperature unit="摂氏">
        <range centigrade="max">27</range>
        <range centigrade="min">24</range>
        </temperature>
        <rainfallchance unit="%">
        <period hour="00-06">20</period>
        <period hour="06-12">20</period>
        <period hour="12-18">20</period>
        <period hour="18-24">30</period>
        </rainfallchance>
    </info>
    

XMLとしては単純です。このXMLドキュメントから次のような形にして表示したいと思います。

  千葉県 北東部
    日時  2015/08/22
      天気  くもり
      天気詳細 南の風 海上 では 南の風 やや強く 晴れ 夕方 から くもり
      波 4メートル うねり を伴う
      気温 24 から27度
      降水確率 00-06 20%
           06-12 20%
           12-18 20%
           18-24 20%
    日時  2015/08/23
       天気  くもり時々晴れ
       天気詳細 北東の風 のち やや強く くもり 所により 夜 雨
       波 4メートル うねり を伴う
       気温 24から27度
       降水確率 00-06 20%
            06-12 20%
            12-18 20%
            18-24 20%
   ・・・・・

気象庁のXML情報(以下XMLドキュメントといいます)のルートタグは<weatherforecast>です。上のように表示するには、このXMLの内、areaタグとその下部要素のinfoタグが必要です。

千葉県の情報なので、prefタグは一つですが、areaタグは複数(3つ)、areaタグの下にも複数のinfoタグがあります。

infoタグの下には、weather、weather_detail、waveタグがあり、更に、複数のtemperatureタグとrainfallchanceタグがあります。

前回ご説明しましたが、SAXはXMLドキュメントを上から順に調べていきます。

調べた情報をどのような形で集めるか。

一番いいのはクラスを定義して、このクラスに情報を書き込んでいくのがいいと思います。SAXがXMLを調査していく過程で、必要な情報をクラスに書き込み、最終的にそのクラス(リスト)を取り出して、更に必要な処理をします。

ここで、クラスAreaを定義します。

Areaのメンバー変数は、AreaName、とInfoサブクラスです。

	public class Area {
		public ArrayList<Info_data> o_Infolst;
		public String AreaName;

		public  class Info_data {
			public String dt;
			public String weather;
			public String weather_detail;
			public int[] range = new int[2];
			public String wave;
			public int[] rainfall = new int[4];
		}
	}

上のクラス定義は概念的なものです。正確ではありません。

さて、JavaでSAXを処理するために、DefaultHandlerクラスがあります。ユーザはこのクラスを継承した独自クラスを定義し、このDefaultHandlerにXMLドキュメントの処理を委ねます。

DefaultHandlerの核心は、startElement、endElementイベントハンドラです。DefaultHandlerがXMLドキュメントを読み進んでいて、開始タグに出会うとstartElementイベントが起動され、終了タグに出会うとendElementイベントが起動します。

その時なにをするかは、プログラマが目的に沿って独自にコードを書きます。

DefaultHandlerにはもう一つ、重要なしかしよくわからないcharactersというメソッドがあります。

DefaultHandlerが要素の内容(Text)に出会うとその内容を取り出すようですが、あまり詳しい動作は分かりません。以下に今回の処理のために作成したSAXコードの主要部分を示します。

public class SAXHandler extends DefaultHandler {

    private ArrayList<Area> o_lstArea = new ArrayList<Area>();
    private Area o_Area;

    private List<Area.Info_data> o_Infos;
    private Area.Info_data o_Info;

    private int rangCnt;
    private int periodCnt;

    private String tempVal;

    public ArrayList<Area> getAllAreaWeather() {
        return o_lstArea;
    }

    @Override
    public void startElement(String nsURI, String strippedName, String tagName,
                             Attributes attributes)   throws SAXException {
        tempVal = "";
        if (strippedName.equalsIgnoreCase("area")) {
            o_Area = new Area();
            o_Area.setAreaName(attributes.getValue("id"));

            o_lstArea.add(o_Area);
        } else if (strippedName.equalsIgnoreCase("info")) {
            o_Info = o_Area.makeInfo();
            o_Info.setDt(attributes.getValue("date"));
        }  else if (strippedName.equalsIgnoreCase("temperature")) {
            rangCnt = 0;
        }  else if (strippedName.equalsIgnoreCase("rainfallchance")) {
            periodCnt = 0;
        }
    }

    @Override
    public void endElement(String name, String localName, String qName) {
        if (qName.equalsIgnoreCase("weather")) {
            o_Info.setWeather(tempVal);
        } else if (qName.equalsIgnoreCase("weather_detail")) {
            o_Info.setWeather_detail(tempVal);
        } else if (qName.equalsIgnoreCase("wave")) {
            o_Info.setWave(tempVal);
        } else if (qName.equalsIgnoreCase("range")) {
            o_Info.getRange()[rangCnt++] = Integer.parseInt(tempVal);
        } else if (qName.equalsIgnoreCase("period")) {
            o_Info.getRainfall()[periodCnt++] = Integer.parseInt(tempVal);
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
            tempVal = new String(ch, start, length);
    }
}

上のコードで、[o_Area.setInfo]や[o_Info.setWeather_detail]等は上では省略したAreaクラスのメソッドです。

SAXHandlerのstartElementイベントでは、SAXがXMLの要素(ノード)を読んだときに新たな[Areaオブジェクト]を作ったり、Areaオブジェクトのサブオブジェクトを作成したり、温度や降水確率用の配列インデックスをクリアしたりしています。

一方のendElementイベントでは、要素の内容(Text)を読みこんだときに、その内容をAreaオブジェクトやInfoオブジェクトに書き込んでいます。

その書き込んでいる情報というのが、charactersで取得しているtempValです。

メインプログラムはSAXHandlerをコールし、SAXHandlerが作成したリスト変数[o_lstArea]を取得し、必要な処理を続けます。

 

ところで、WindowsプログラムではSAXを使いません。同等のクラスとしてXmlReaderがあります。

SAXでは、XMLドキュメントの処理をSAXHandler(DefaultHandler)が処理します。すなわち、処理はSAXHandlerの中に記述しますが、XmlReaderはXMLドキュメントを読み込むだけで、あとはコール側で処理プログラムを書きます。

同じようなものですが、XmlReaderにはcharactersのようなよくわからないメソッドはなく、すべて可視的なので、趣味の問題かもしれませんがXmlReaderの方が安心できます。

更に、Windowsにはデータ処理の手法として標準でLINQがあり、[LINQ to XML]はXML処理に関してはもっと簡単かもしれません。

次回は、XmlReaderではこの問題をどのようにコーディングするのか、ご紹介します。続いて、XSLTのご紹介もしたいと思います。

XML ドキュメントの処理

XMLというのは、言語仕様で、2000年ころからコンピュータ分野で広く採用されるようになりました。

単純な例を次に示します。

    <employees>
     	<employee id="101">
      		<firstName>Taro</firstName>
      		<lastName>Yamada</lastName>
    			・・・・・
     	</employee>
     	<employee id="102">
      		<firstName>Jiro</firstName>
      		<lastName>Suzuki</lastName>
    			・・・・・
     	</employee>
    		・・・・・
  </employees>

これは従業員名簿ですが、当然二人だけでなく沢山でいいし、項目も職種とか給与とか資格とか色々あるでしょう。階層も必要なだけ深くなっても構いません。

幾つか注意点があります。XMLファイル(ドキュメント)は、一つのルートを持つ木構造になっているということです。上の例では、木の根っこルートは<employees>です。一つのXMLドキュメントに複数のルートがあってはいけません。枝が絡み合ってもいけません。

幾つかのキーワードをご紹介します。
employees、employee 、firstName、lastName等はタグ(名)とわれ、タグは必ず開始タグと対応する終了タグがなければ以下ません。開始タグは[<]と[>]で囲まれ、終了タグは[< /]と[>]で囲われます。

上の例では、<employees>は開始タグ、</employees>は終了タグです。特殊な例としては、<employees id=”1″ firstName=”Hanako” />のように開始タグと終了タグが一つになることも有ります。

タグの中に書かれた上の例で、[id=”101″]は属性と言われます。

開始タグと終了タグで囲まれた部分を要素と言います。
上の例で、<firstName>Taro</firstName>は要素ですし、<employee id=”101″><firstName>Taro</firstName><lastName>Yamada</lastName></employee>は要素です。タグで囲まれた文字列は要素の内容と言います。TaroやYamadaやJiroやSuzukiは要素の内容です。

特に子要素をもつタグを節(ノード)と言います。木構造で枝分かれする付け根の部分=節に当たります。

 

ところで、上の例で「Jiro君の苗字は?」と聞かれて、「彼のの苗字はSuzuki」ですとすぐわかります。

これをコンピュータでどのように処理すればいいのか。という問題です。

現在二つの手法が提案されています(WindowsにはLINQ等専用の手法があります)。すなわち、SAXとDOMです。

SAXは、頑なにXMLドキュメントのルートから始まり、順に問いにたどり着こうとするものです。

上の例では、employees開始-> employee開始-> firstName開始->firstName終了->lastName開始->lastName終了-> ・・・・ ->employee終了

で最初のemployee検査を終了し、続いて次のemployeeの検査に進み、employee開始-> firstName開始「あ、見つかった」と必要な情報にたどり着き、あとはプログラムによって、色々な処理方法があると思います。今ここで重要なのは、SAXはこのように最初から順々に探していくということです。

一方のDOMは、ドキュメント全体を探し始めます。たとえば、firstNameタグを全部集めて、そこからJiroを探し出し、Jiro情報から直接lastNameタグのSuzukiを見つける方法です。

 

情報の抽出ではなく、XMLドキュメントを次の処理に扱いやすい新たなXMLドキュメントに変換する手法が、XLSTです。

Wordで単純な文章を作って、XML形式で書き出してみてください。驚ろくほど長文の複雑なXML形式の文章が出力されます。

一般にプログラムで機械的に出力されたXMLドキュメントは複雑な形をしています。扱いやすい形あるいは必要な形に成形してから、次の処理に回そうとか、そのままブラウザで表示しようとかのときは、XSLTはとても有効です。

個人的には、そのプログラミングはゲームやマジックを解くような感覚になり、とても楽しい作業です。

DOMやXSLTは10年以上前にやった経験がありますが、今はもうほとんど覚えていません。SAXはこれまでやったことがなかったし、興味があったので簡単な例で試してみました。

次回ご紹介します。