2013年1月15日火曜日

svgの記述ミスを効率良く確認する方法

手描きでsvgを記述するとよくやるのがxmlの構文間違いと要素名や属性名の記述間違いです.どちらも期待した結果が得られないといった点で共通しているのですが,特に後者はxmlとして辻褄があってしまう上に,ブラウザによっては正しく動作してしまう場合があるなど侮れません.一般的なプログラム言語においては何かしらチェック機構が提供されているわけですから,2次元ベクタ画像描画スクリプトたるsvgにおいても何らかのテクニックがあって然るべきです.


svgにおける二つの記述ミス


例えば次のコードはどこが間違っているでしょう?

<?xml version="1.0" standalone="no"?>
<svg width="100px" height="100px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
 <title>sample</title>
 <defs><rect width="100" height="100" id="a"></defs>
 <use xlink:href="#a"/>
</svg>

正解はuse要素の記述が開始タグとなっている点です.ここは「/>」と記述してシングルタグとすべきです.これはwebブラウザでファイルを開くだけで検証出来るエラーです.


では次はどうでしょう?先ほどと同様に一箇所間違っています.

<?xml version="1.0" standalone="no"?>
<svg width="100px" height="100px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
 <title>sample</title>
 <def><rect width="100" height="100" id="a"/></def>
 <use xlink:href="#a"/>
</svg>

一見問題が無さそうに見えるし,ブラウザでも正しく動作するのでxmlとしても妥当なようです.ですが,def要素はsvgでは定義されていません.つまりここはdefs要素とすべきなのです.

今回はuse要素による図形の参照だったためそれほど大きな問題とはなりませんでしたが,場合によっては非常に面倒な問題を引き起こします.例えば「def要素」内部のグラデーション要素はchromeにおいて無視されます

このようにxmlとしての構文エラーだけでなく,svgとしての構造エラーの検知機構が欲しくなるところです.

dtdファイルを使ったエラー検知


実はこの問題はsvgのドキュメントタイプを定義しているdtdファイルを利用することで解決します.このdtdファイルはw3cで配布しており,ここから入手することができます.これをxmlの妥当性判断ツールに読み込ませてsvgとしての整合性をチェックするのです.一般にxmlの妥当性判断にdtdを利用すべきでないとの見解もありますが,既にあるものを利用しない手はありません.

例えば筆者の環境ubuntuではxmlstarletコマンドを利用することでこのチェックを行うことができます.システムにインストールされていなければapt-get等で導入しておきましょう.windows環境であればmsxmlを使えば良いかと思います.

ここで,次のようなコマンドを実行することでsvgの構造チェックを行います.w3cから入手したdtdファイルはsvgファイルと同じディレクトリに保存されているものとします.

a@a:~$ xmlstarlet val -e -d svg11-flat.dtd document.svg
document.svg:2.0: Element svg content does not follow the DTD, expecting (desc | title | metadata | animate | set | animateMotion | animateColor | animateTransform | svg | g | defs | symbol | use | switch | image | style | path | rect | circle | line | ellipse | polyline | polygon | text | altGlyphDef | marker | color-profile | linearGradient | radialGradient | pattern | clipPath | mask | filter | cursor | a | view | script | font | font-face | foreignObject)*, got (title def use )
document.svg:4.0: No declaration for element def
document.svg - invalid
a@a:~$

出力結果を見てみましょう.どうやら2行目と4行目に問題があるようです.内容を見ると「def」要素が定義されていないとのことです.このように問題のあるコード部分を抽出することが出来ました.なお,この方法ではxmlとしての構文チェックを行うこともできます.

それほど試しているわけでないため全ての場合に対処できるかはいまいち不明ですが,svgのチェック機構が増える分には問題部分の洗い出しの面で有効だと思います.

なお,これ以外にも属性に設定する内容を間違えたと言ったケースも考えられますが,この場合はwebブラウザのデバッガでエラーとして検知できるため,先ほどの構造に関わるエラーほど深刻ではありません.

まとめ


svgのエラーを確認するには次の3つを活用しよう
  • webブラウザで開く…構文のエラー
  • xmlの妥当性判断を行う…構造のエラー
  • webブラウザのデバッガを確認する…設定値のエラー

0 件のコメント:

コメントを投稿