四則演算のXML Schema
Scala に wonderfl のゲームを移植しようとして諦めてしまった今日この頃、いかがお過ごしでしょうか?
自分は仕事でXML Schemaをやりそうで、やってません。
でも、XML Schemaを久しくいじってなかったので勉強しようとして、
俺言語プログラマ的には、四則演算のXMLのバリデーションができるサンプルがほしいと
思ってググってみるも、見つからない。むぅ。
Visual Studio と MSDN だけだと、わかりずらい。むぅ。
いいエディタなんかないか?ってさがすと、NetBeansのXMLスキーマが案外よさそう。
ってことで、使ってみたら、MSDN+ Visual Studioより自分の場合はわかりやすくできました。
おお、すばらしい。
ということで、まず、バリデーションしたいXMLが以下のようになります。
<?xml version="1.0" encoding="UTF-8"?> <exp xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://xml.netbeans.org/schema/exp' xsi:schemaLocation='http://xml.netbeans.org/schema/exp exp.xsd'> <add> <div> <sub> <number>2</number> <number>2</number> </sub> <number>3</number> </div> <add> <number>2</number> <number>2</number> </add> </add> </exp>
expがルートのタグでその下に、add,mul,sub,divという演算子用タグとnumberという数値用タグが入れられます。
で、演算子タグは2つの子要素をもてますというやつです。再帰的に文法を定義できるといいなというところ。
で、これに対応する XML Schema がこちら。
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://xml.netbeans.org/schema/exp" xmlns:tns="http://xml.netbeans.org/schema/exp" elementFormDefault="qualified"> <xsd:element name="exp"> <xsd:complexType> <xsd:group ref="tns:exp"/> </xsd:complexType> </xsd:element> <xsd:group name="exp"> <xsd:choice> <xsd:element name="number"> <xsd:simpleType> <xsd:restriction base="xsd:short"/> </xsd:simpleType> </xsd:element> <xsd:element name="add"> <xsd:complexType> <xsd:sequence> <xsd:group ref="tns:exp"/> <xsd:group ref="tns:exp"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="sub"> <xsd:complexType> <xsd:sequence> <xsd:group ref="tns:exp"/> <xsd:group ref="tns:exp"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="mul"> <xsd:complexType> <xsd:sequence> <xsd:group ref="tns:exp"/> <xsd:group ref="tns:exp"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="div"> <xsd:complexType> <xsd:sequence> <xsd:group ref="tns:exp"/> <xsd:group ref="tns:exp"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:group> </xsd:schema>
簡単に説明すると、まず、schemaタグがルートのタグでその下あるelementタグがルート要素になりうるタグになります。今回はexpタグをルートにしたいので、
XML Schemaのタグは全部xsd:をつけて書くぜってかんじですな。
で、elementタグ以下のcomplexTypeとかいうのが、最初なんだ?complex?虚数?とか思うのですが複合型といわれる型です。Cとかだとstructやらclassみたいなものと考えるとわかりやすいかと。大してプリミティブな型みたいなのがsimpleTypeだと。simple型は、intとかstringとか組み合わせもなんもない型が主だと思ってしまいましょう。
すると、今回のexpの下にはいろんなタグが入るからcomplexTypeを選択するしかないわけです。ってことでそれがcomplexTypeです。
で、その下に
なんで、groupを使っているのかというと、elementだけで定義すると限界があったからです。
どんな限界かというと、下の例を見てもらいたいと。
<?xml version="1.0" encoding="UTF-8"?> <!-- xml schema の定義は、schemaタグ内に書く--> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://xml.netbeans.org/schema/exp1" xmlns:tns="http://xml.netbeans.org/schema/exp1" > <!-- xmlns:xsd="http://www.w3.org/2001/XMLSchema"は xsdネームスペースに http://www.w3.org/2001/XMLSchema を使う。xsd:...タグはXMLSchemaのタグだ!ってこと targetNamespace="http://xml.netbeans.org/schema/exp1"は 今回作るスキーマのネームスペースは"http://xml.netbeans.org/schema/exp1"ってこと。 xmlns:tns="http://xml.netbeans.org/schema/exp1"は ちょうど今回作るスキーマのネームスペースをtnsとするってこと。tnsはtarget name spaceの略だ! --> <xsd:element name="exp"> <!-- schemaタグ以下にあるelementタグはルートになりうるタグだ! expタグが親になるってことのことよ。 --> <xsd:complexType> <!--complexTypeは複合型のこと。対してsimpleType(単純型)ってのもある。素数のことではない。マザコンのアレでもない。--> <xsd:choice><!--choiceは選択である。これ以下の要素の中から1つ選べっちうかんじ。--> <xsd:element name="number"><!--numberタグ(数値タグ)の定義をする。--> <xsd:simpleType><!--number方は単純型である--> <xsd:restriction base="xsd:short"/><!--number型の型はshortだ!それ以外は許さん!--> </xsd:simpleType> </xsd:element> <xsd:element name="add"><!--addタグ(足し算タグ)の定義をする--> <xsd:complexType><!--addタグは式と式を入れられるから複合型とする--> <xsd:sequence><!--addタグには2つ要素を連続で入れたい。そういう場合はsequence(連続)を使ったらよい。--> <xsd:element ref="tns:exp"/><!--addタグにはexpタグが入るぜってこと。refは参照の意味で関数の再起呼び出しみたいなかんじ。--> <xsd:element ref="tns:exp"/><!--もう一個書く--> </xsd:sequence> </xsd:complexType> </xsd:element> <!--addタグコピッて、name=subとしただけで足し算の完成だ!--> <xsd:element name="sub"> <xsd:complexType> <xsd:sequence> <xsd:element ref="tns:exp"/> <xsd:element ref="tns:exp"/> </xsd:sequence> </xsd:complexType> </xsd:element> <!--addタグコピッて、以下省略だ--> <xsd:element name="mul"> <xsd:complexType> <xsd:sequence> <xsd:element ref="tns:exp"/> <xsd:element ref="tns:exp"/> </xsd:sequence> </xsd:complexType> </xsd:element> <!--addタグコピッて、以下しょうry)--> <xsd:element name="div"> <xsd:complexType> <xsd:sequence> <xsd:element ref="tns:exp"/> <xsd:element ref="tns:exp"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema> <!--ってことで完成である-->
これだと、以下のようなxmlしか扱えなくて悲しいのです。
<exp> <add> <exp><number>1</number></exp> <exp> <add> <exp><number>1</number></exp> <exp><number>1</number></exp> </add> </exp> </add> </exp>
とまぁ、expうざってことです。ということで疲れたのでこの辺で。
と、ぜんぜん、NetBeans使ってないんですけどっていう気もするんですけど、
XMLスキーマのexp.xsdとかいうファイルがあったら、
ソース、スキーマ、デザインってあって、スキーマのタブクリックしといて、あとは複合型とか選ぶと
なんか、それっぽいのができてって楽だったのでした。
なんとなく、こんなかんじにしたいっていうのが、やってけばそれなりの形になってくれてうれしいという。
それが、visual stdioだと、こう、したいのだけど、どうやったらなるのか謎のまま時が過ぎてってイライラ。
うー、解説になってない。墓穴ほってるな。
ってことで、とりあえず、触ってみてください。