RELAX NG Compact Syntax
はじめに
書いてみるとRELAX NGってのは結構長い.XML形式ではないRELAX NG Compact Syntaxというのがあるので,そっちを使ってみることにする.RELAX NGでスキーマ記述でつくったRELAX NGのスキーマを書き換えることにしよう.
root要素
とりあえず,root要素と属性title,その直下にあるimg,content,p,ancherの各要素を書いてみる.参考までに,DTDも載せてみた.
RELAX NG | RELAX NG Compact Syntax | DTD |
---|---|---|
<element name="root"> <attribute name="title"> <text/> </attribute> <element name="img"> </element> <oneOrMore> <element name="content"> </element> </oneOrMore> <element name="p"> </element> <zeroOrMore> <element name="ancher"> </element> </zeroOrMore> </element> |
element root{ attribute title{text}, element img{}, element content{}+, element p{}, element ancher{}* } |
<!ELEMENT root (img,content+,p,ancher*)> <!ATTLIST root title CDATA #REQUIRED> |
キーワードelement
は要素,attribute
は属性を表している.キーワードの後ろに要素名,または属性名.要素名・属性名の後には{}
をつけ,子要素やデータ型を記述する.
要素が順番に出現する場合は“,”で繋げる.“*”は0回以上の繰り返し,“+”は1回以上の繰り返しである.0もしくは1回は“?”となる.したがって,意味するところは以下の通りとなる.
- 要素rootには属性titleと子要素img,content,p,ancherがある.
- 属性titleは文字列.
- 子要素img,content,p,ancherはこの順番で記述する.
- contentは1回以上の繰返し.
- ancherは0回以上の繰返し.
img要素
img要素はwidth・height・src・alt属性を持つ空要素である.空要素なのでキーワードemptyをつける.
RELAX NG | RELAX NG Compact Syntax | DTD |
---|---|---|
<element name="img"> <attribute name="width"> <text/> </attribute> <attribute name="height"> <text/> </attribute> <attribute name="src"> <text/> </attribute> <attribute name="alt"> <text/> </attribute> <empty/> </element> |
element img{ attribute width{text}, attribute height{text}, attribute src{text}, attribute alt{text}, empty } |
<!ELEMENT img EMPTY> <!ATTLIST img width CDATA #REQUIRED height CDATA #REQUIRED src CDATA #REQUIRED alt CDATA #REQUIRED> |
content要素
content要素はテキストとul要素の混合型である.ulはあってもなくても良い.
RELAX NG | RELAX NG Compact Syntax | DTD |
---|---|---|
<oneOrMore> <element name="content"> <attribute name="href"> <text/> </attribute> <attribute name="name"> <text/> </attribute> <mixed> <optional> <element name="ul"> </element> </optional> </mixed> </element> </oneOrMore> |
element content{ attribute href{text}, attribute name{text}, mixed{ element ul{ }? } }+, |
<!ELEMENT content (#PCDATA|ul)*> <!ATTLIST content href CDATA #REQUIRED name CDATA #REQUIRED> |
ulの下位要素として一つ以上のli要素と混合型のa要素があるので,全部書くとこうなる.
RELAX NG | RELAX NG Compact Syntax | DTD |
---|---|---|
<oneOrMore> <element name="content"> <attribute name="href"> <text/> </attribute> <attribute name="name"> <text/> </attribute> <mixed> <optional> <element name="ul"> <oneOrMore> <element name="li"> <mixed> <ref name="a"/> </mixed> </element> </oneOrMore> </element> </optional> </mixed> </element> </oneOrMore> |
element content{ attribute href{text}, attribute name{text}, mixed{ element ul{ element li{ mixed{ element a{ attribute href{text}, text } } }+ }? } }+, |
<!ELEMENT content (#PCDATA|ul)*> <!ATTLIST content href CDATA #REQUIRED name CDATA #REQUIRED> <!ELEMENT ul (li+)> <!ELEMENT li (#PCDATA|a)*> <!ELEMENT a (#PCDATA)> <!ATTLIST a href CDATA #REQUIRED> |
全体像
こうしてできあがったのがこれ.
RELAX NG | RELAX NG Compact Syntax | DTD |
---|---|---|
<?xml version="1.0" encoding="utf-8"?> <element name="root" xmlns="http://relaxng.org/ns/structure/1.0"> <attribute name="title"> <text/> </attribute> <element name="img"> <attribute name="width"> <text/> </attribute> <attribute name="height"> <text/> </attribute> <attribute name="src"> <text/> </attribute> <attribute name="alt"> <text/> </attribute> <empty/> </element> <oneOrMore> <element name="content"> <attribute name="href"> <text/> </attribute> <attribute name="name"> <text/> </attribute> <mixed> <optional> <element name="ul"> <oneOrMore> <element name="li"> <mixed> <element name="a"> <attribute name="href"> <text/> </attribute> <text/> </element> </mixed> </element> </oneOrMore> </element> </optional> </mixed> </element> </oneOrMore> <element name="p"> <mixed> <element name="a"> <attribute name="href"> <text/> </attribute> <text/> </element> </mixed> </element> <zeroOrMore> <element name="ancher"> <attribute name="href"> <text/> </attribute> <element name="banner"> <attribute name="src"> <text/> </attribute> <attribute name="alt"> <text/> </attribute> <empty/> </element> </element> </zeroOrMore> </element> |
element root{ attribute title{text}, element img{ attribute width{text}, attribute height{text}, attribute src{text}, attribute alt{text}, empty }, element content{ attribute href{text}, attribute name{text}, mixed{ element ui{ element li{ mixed{ element a{ attribute href{text}, text } } }+ }? } }+, element p{ mixed{ element a{ attribute href{text}, text } } }, element ancher{ attribute href{text}, element banner{ attribute src{text}, attribute alt{text}, empty } }* } |
<!ELEMENT root (img,content+,p,ancher*)> <!ATTLIST root title CDATA #REQUIRED> <!ELEMENT img EMPTY> <!ATTLIST img width CDATA #REQUIRED height CDATA #REQUIRED src CDATA #REQUIRED alt CDATA #REQUIRED> <!ELEMENT content (#PCDATA|ul)*> <!ATTLIST content href CDATA #REQUIRED name CDATA #REQUIRED> <!ELEMENT ul (li+)> <!ELEMENT li (#PCDATA|a)*> <!ELEMENT a (#PCDATA)> <!ATTLIST a href CDATA #REQUIRED> <!ELEMENT p (#PCDATA|a)*> <!ELEMENT ancher (banner)> <!ATTLIST ancher href CDATA #REQUIRED> <!ELEMENT banner EMPTY> <!ATTLIST banner src CDATA #REQUIRED alt CDATA #REQUIRED> |
名前付きパターン
RELAX NG同様,RELAX NG Compact Syntaxでも名前付きパターンを使うことができる.DTDには名前付きパターンはない.
RELAX NG | RELAX NG Compact Syntax |
---|---|
<?xml version="1.0" encoding="utf-8"?> <grammar xmlns="http://relaxng.org/ns/structure/1.0"> <start> <element name="root"> <attribute name="title"> <text/> </attribute> <ref name="img"/> <oneOrMore> <ref name="content"/> </oneOrMore> <ref name="p"/> <zeroOrMore> <ref name="ancher"/> </zeroOrMore> </element> </start> <define name="img"> <element name="img"> <attribute name="width"> <text/> </attribute> <attribute name="height"> <text/> </attribute> <attribute name="src"> <text/> </attribute> <attribute name="alt"> <text/> </attribute> <empty/> </element> </define> <define name="content"> <element name="content"> <attribute name="href"> <text/> </attribute> <attribute name="name"> <text/> </attribute> <mixed> <optional> <element name="ul"> <oneOrMore> <element name="li"> <mixed> <ref name="a"/> </mixed> </element> </oneOrMore> </element> </optional> </mixed> </element> </define> <define name="p"> <element name="p"> <mixed> <ref name="a"/> </mixed> </element> </define> <define name="ancher"> <element name="ancher"> <attribute name="href"> <text/> </attribute> <element name="banner"> <attribute name="src"> <text/> </attribute> <attribute name="alt"> <text/> </attribute> <empty/> </element> </element> </define> <define name="a"> <element name="a"> <attribute name="href"> <text/> </attribute> <text/> </element> </define> </grammar> |
start= element root{ attribute title{text}, img, ←要素でも属性でもなく名前付きパターン content+, ←要素でも属性でもなく名前付きパターン p, ←要素でも属性でもなく名前付きパターン ancher* ←要素でも属性でもなく名前付きパターン } img= ←名前付きパターンの定義 element img{ attribute width{text}, attribute height{text}, attribute src{text}, attribute alt{text}, empty } content= element content{ attribute href{text}, attribute name{text}, mixed{ element ul{ element li{ mixed {a} }+ }? } } p= element p{ mixed{a} } ancher= element ancher{ attribute href{text}, element banner{ attribute src{text}, attribute alt{text}, empty } } a= element a{ attribute href{text}, text } |
Trangで変換
これまで,手で書いてきたが,Trangを使うとDTDとRELAX NGとRELAX NG Compact Syntaxの三つのスキーマを変換しあうことができる.RELAX NGからRELAX NG Compact Syntaxを作ってみる.trang.jarがカレントディレクトリにある前提の場合,このようなコマンドになる.
$ java -jar trang.jar index.rng index.rnc
第一引数が入力ファイル,第二引数が出力ファイル.これらのファイルの拡張子で,入力・出力のスキーマを判定する.拡張子.rng
がRELAX NG,.rnc
がRELAX NG Compact Syntaxである.