* : [cl][xml][cxml][xml catalog]
XML関係のディレクトリのまとめ。
~/local/lib/catalog/
; カタログ関係置き場
~/local/lib/catalog/catalog
; XML Catalogのcatalog xmlファイル。
; cxmlもこれを使う。
~/local/lib/schema
; rnc置き場。nxml-modeで参照している。
~/local/lib/xml
; linuxから移植したもの。
;declaration
;entities
;misc
;schema
;という4つのディレクトリを持つ。
;これら4つの名称から、XMLの外部エンティティ格納用だろう。
~/local/lib/xml-core
; linuxから移植したもの。
; なんのために存在するのかいまいちわからない。
将来再整備すべきだが、現状はこんな感じ。
* : [cl][xml][cxml][xml catalog]
さて、cxmlにおけるschemaとvalidationの話。
まずXML仕様で定義しているschemaはDTDのみである。なので、XML仕様に
準拠したXML processorである、といったときにはDTDは取り扱えなければ
ならないし、他の形式のSchemaを取り扱える必要はない。
DTDにはinternal subsetとexternal subsetがある。
ポイントは、共通のDTDをexternal subsetとしたときにそれをどう取り扱
うかだろう。
まず第一にはXML文書にsystem idが記載されており、そのURIが、使って
いるXML processorが取得対応している形式ならば、そこから取得すると
いうやり方。
cxmlの場合はローカルのファイルシステムからは取得できるが、そのまま
ではhttpに対応していないため、httpをスキーマとするURIについてはエ
ラーとなる。
cxmlでは、これをエラーとしないための迂回作が2つある。
ひとつは、entity resoloverで、ローカルファイルで差し替えちゃう方法。
---
(flet ((resolver (pubid sysid)
(declare (ignore pubid sysid))
(flexi-streams:make-in-memory-input-stream nil)))
(cxml:parse-file "dtdexample.xml" (cxml-dom:make-dom-builder)
:entity-resolver #'resolver))
---
もうひとつは、entity resoloverで、そのURIから取ってきちゃう方法。
---
(flet ((resolver (pubid sysid)
(declare (ignore pubid))
(when (eq (puri:uri-scheme sysid) :http)
(drakma:http-request sysid :want-stream t))))
(cxml:parse-file "dtdexample.xml" (cxml-dom:make-dom-builder)
:entity-resolver #'resolver))
---
ここではdrakmaというライブラリを使用している。
さて、第二の方法はXML Catalogsを使う方法である。
これはXML processorがXML Catalogsに対応している必要がある。
XML Catalogsの仕様はOASISで標準化されており、
http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
が仕様書である。
XML Catalogsというのは、簡単にいえば、XML文書の中に現われるpublic
identifierやsystem identifierやURIの代替をXML processorに渡すため
の設定ファイルである。
現在、私の環境のcatalogファイルは次のとおり。
---
<?xml version="1.0"?>
<!DOCTYPE catalog PUBLIC "-//OASIS//DTD XML Catalogs V1.0//EN"
"file:///Users/aka/local/lib/xml/schema/xml-core/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<delegatePublic publicIdStartString="-//OASIS//DTD XML Catalogs V1.0//EN" catalog="file:///Users/aka/local/lib/xml/schema/xml-core.xml"/>
<delegateSystem systemIdStartString="http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd" catalog="file:///Users/aka/local/lib/catalog/xml-core.xml"/>
<group xml:base="file:///Users/aka/local/lib/xml/schema/xhtml1.0/">
<puublic publicId="-//W3C//DTD XHTML 1.0 Strict//EN" uri="xhtml1-strict.dtd"/>
<public publicId="-//W3C//ENTITIES Latin 1 for XHTML//EN" uri="xhtml-lat1.ent"/>
<public publicId="-//W3C//ENTITIES Symbols for XHTML//EN" uri="xhtml-symbol.ent"/>
<public publicId="-//W3C//ENTITIES Special for XHTML//EN" uri="xhtml-special.ent"/>
<system systemId="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" uri="xhtml1-strict.dtd"/>
</group>
</catalog>
---
cxmlでは次のようにこれを利用できる。
---
;;catalogを使わずにxhtmlをパース
(setf cxml:*catalog* nil)
(cxml:parse #p"test.xhtml" (stp:make-builder)) ; error,DTDを取得できない。
;;catalogを使ってxhtmlをパース
(setf cxml:*catalog* nil)
(setf cxml:*catalog* (cxml:make-catalog (list "/Users/aka/local/lib/catalog/catalog")))
(cxml:parse #p"test.xhtml" (stp:make-builder)) ; errorにならない。
---
次回はcxml-rng。
こつこつ。
0 件のコメント:
コメントを投稿