XSLTプロセッサのxsltprocがべんり

google maps API で、openInfoWindowXslt() がネイティブのXSLTプロセッサがなかったらjs実装にfallbackするよとか書いてあるけど実際には動かなかったので(google maps APIが2になってGXsltでXSLTを扱うようになってからどうなったのかは知らないです)使わなくなっちゃったけど、XSLTを使うとよくわかんないjsをがんばって書いてHTML作るよりもはるかにすっきりきれいなコードになったのは覚えている。
webだとあんまりデータをXMLでは扱わなくて、RSSとかXMLHttpRequest()でちょこっとでてきたけど、前者はライブラリ経由で触るとただのツリー型のデータでXMLだと意識することはあまりないし、後者も主流はJSONになって(StoryOfXmlhttp – XMLHTTP の話。 からすれば当然なのかも)、やっぱり使わなくなった。なのでXSLTとかいうと、まわりにあんまりいい顔されない。

でも firefox extension を作っていて、これはぜったいXSLTだというのがあった。
firefox extension にはextensionについての情報を記述する install.rdf というファイルがあり、これにそのextensionのバージョンや、extensioが動作するfirefoxのバージョン、対象となるアプリケーションのguid等、いろいろな情報が書かれている。実際の中身の一部を取り出すとこんな感じ。

  <Description about="urn:mozilla:install-manifest">
    <em:id>jsswitch@ido.nu</em:id>
    <em:name>jsswitch</em:name>
    <em:version>0.1.3</em:version>
        <em:description>an extension just to switching javascript on/off.</em:description>
    <em:homepageURL>http://ido.nu/kuma/jsswitch</em:homepageURL>
    <em:updateURL>http://ido.nu/kuma/jsswitch/update.rdf</em:updateURL>
    <em:targetApplication>
      <Description>
        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- firefox -->
        <em:minVersion>2.0</em:minVersion>
        <em:maxVersion>2.0.0.*</em:maxVersion>
      </Description>
    </em:targetApplication>
  </Description>

extensionについての情報が書かれたこのinstall.rdfの中に

  <em:updateURL>

というノードがある。Firefoxは、extensionの新しいバージョンがあるかを確認するときに、このノードに書かれたURLにアクセスして、その中に書かれているバージョンを見て新しいバージョンがあるかどうかを知るようになっている。このノードに書かれたURLにファイルを置いておくことで新しいバージョンがあるかどうかをFirefoxに伝えることができる。ファイルの名前は何でもいいのだけれど仮に update.rdf としておく。この update.rdf は重要なところだけを抜き出すと

<RDF:Description>
  <em:version>0.1.3</em:version>
  <em:targetApplication>
    <RDF:Description>
    <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
    <em:minVersion>2.0</em:minVersion>
    <em:maxVersion>2.0.0.*</em:maxVersion>
    <em:updateLink>http://ido.nu/jsswitch/jsswitch.xpi</em:updateLink>
    </RDF:Description>
  </em:targetApplication>
</RDF:Description>

こうなっている。

extensionを新しくするたびに、このふたつのファイルのバージョン部分をアップデートしないといけないけれど、install.rdfはともかくupdate.rdfはきっとアップデートし忘れる。手で書き換えていたら自分だったら絶対忘れる。さらに対応しているバージョンはたまにしか変更しないぶん、変更したときにはきっと変え忘れる。

だからXSLTでinstall.rdfからupdate.rdfを生成することにした。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:em="http://www.mozilla.org/2004/em-rdf#"
  xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>
  <xsl:output method="xml" encoding="utf-8" indent="yes"/>
  <xsl:template match="/">
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:em="http://www.mozilla.org/2004/em-rdf#">
    <RDF:Description about="urn:mozilla:extension:jsswitch@ido.nu">
      <em:updates>
        <RDF:Seq>
          <RDF:li>
            <RDF:Description>
              <em:version><xsl:apply-templates select="//em:version"/></em:version>
              <em:targetApplication>
                <RDF:Description>
                  <em:id><xsl:apply-templates select="//em:targetApplication//em:id"/></em:id>
                  <em:minVersion><xsl:apply-templates select="//em:targetApplication//em:minVersion"/></em:minVersion>
                  <em:maxVersion><xsl:apply-templates select="//em:targetApplication//em:maxVersion"/></em:maxVersion>
                  <em:updateLink>http://ido.nu/kuma/jsswitch/jsswitch.xpi</em:updateLink>
                </RDF:Description>
              </em:targetApplication>
            </RDF:Description>
          </RDF:li>
        </RDF:Seq>
      </em:updates>
    </RDF:Description>
</RDF:RDF>
  </xsl:template>
</xsl:stylesheet>

これをstyle.xslとして保存して

xsltproc style.xsl install.rdf  > update.rdf

とすればinstall.rdfをもとに自動でupdate.rdfが生成できてバージョンあげ忘れとかなくなります!
XSLTシロウトなので、きっと冗長なんだとおもうのでこう書いたらもっと楽とかあったら教えてください…

そんなに使う場面がないですがXSLTべんりなのでこんなときには使ってみてください。
LinuxでもOSXでもふつうにインストールしたらはじめから入っているのでぜひ。

いろいろおしえてくれたみやけんさんありがとう。


About this entry