| Minervaは、XML項の処理(read/modify/write)をサポートします。
XML項を読み書きするための4つの述語があります。
- write_xml/1/2
- read_xml/2/3
There are also a couple of predicates for converting lowlevel
XML terms to highlevel MINERVA terms and vice versa.
- term2xml/3
- term2xmldoc/3
- xml2term/3
- xmldoc2term/3
XML項のための型定義
それらのジョブをするために、変換述語(高レベルと低レベルの XML項の間での変換)は、XML項の型の記述を必要とします。 型定義は、以下のフォーマットを持ちます:
TypeDefinition =
MarkupName(AttributeAndSubElementType ...)
% example: addressbook(type=enum([private,business]), any * Address)
AttributeAndSubElementType =
AttributeType
AttributeAndSubElementType =
ElementType
AttributeType =
AttributeName = BasicType
% example: type = enum([private,business])
AttributeType =
AttributeName = opt(BasicType,DefaultValue)
% example: language = opt(atom, english)
ElementType =
(ElementType, ElementType)
% example: (title(-atom),author(firstname(-atom),name(-atom)),price(-number))
ElementType =
(ElementType; ElementType)
% example: (book(title(-atom),author(Autor));journal(title(-atom),volume(-integer)))
ElementType =
Count * ElementType
% example: book(title(-atom),author(Autor),(0,5)*coautor(Autor))
ElementType =
- BasicType
% example: year(-integer)
ElementType =
TypeDefinition
Count =
(Min,Max)
Count =
Integer
% "N * Type" is equivalent to "(N,N) * Type"
Count =
any
% "any * Type" is equivalent to "(0,inf) * Type"
Count =
opt
% "any * Type" is equivalent to "(0,1) * Type"
Count =
some
% "any * Type" is equivalent to "(1,inf) * Type"
Min =
NonNegativeInteger
Max =
NonNegativeInteger
Max =
inf
BasicType =
atom
BasicType =
integer
BasicType =
float
BasicType =
number
BasicType =
boolean
BasicType =
enum([Name, ...])
例題
XML項の処理は、以下の例題から簡単に参照することができます。
あなたがXMLファイルで、あなたの友人のアドレスを集めたと想定して下さい。
これは、以下のフォーマットを持ちます:
John
35
Henriette
27
現在、あなたはMINERVAの中でaddressbookを読みたいです。 open/3でXMLファイルを開き、read_xml/2でXML項を読みます。
main([XmlFilename]) :-
open(XmlFilename, read, XmlStream),
read_xml(XmlStream, XmlTerm),
close(XmlStream),
writeq(XmlTerm),
nl.
このプログラムを呼ぶと、以下の出力をもらいます。
document([xml([version = '1.0'])],
element(addressbook,[],[
element(address,[telno = '1234567'],[
element(name,[],[chardata('John')]),
element(age,[],[chardata('35')])]),
element(address,[telno = '3456789',email = 'henriette@ifcomputer.com'],[
element(name,[],[chardata('Henriette')]),
element(age,[],[chardata('27')])])]),[])
そうして、あなたはXMLファイルを読んで、MINERVA項としてこのファイルの中身を手にいれました。
あなたは、この項を調べることができて、それを処理することができて、別のファイルへそれを書き込むことができます。
例えば、あなたは同じフォーマットの、2つのアドレス張をを持ち、一つにはあなたの友人のアドレスを含み、もう一つにはあなたのビジネス・パートナーのアドレスを入れるとします。 あなたは、2つのアドレス張を1つにマージすることができます。
main([Friends,BusinessPartner,NewAddrBook]) :-
read_xmlfile(Friends,Book_1),
read_xmlfile(BusinessPartner,Book_2),
merge_books(Book_1, Book_2, Book),
write_xmlfile(NewAddrBook, Book).
read_xmlfile(Filename, XmlTerm) :-
open(Filename, read, Stream),
read_xml(Stream, XmlTerm),
close(Stream).
merge_books(
document(_,Addr_1,_),
document(_,Addr_2,_),
document([xml([version = '1.0'])], Elements, [])) :-
append(Addr_1, Addr_2, Addr),
sort(Addr, Elements).
write_xmlfile(Filename, XmlTerm) :-
open(Filename, write, Stream),
write_xml(Stream, XmlTerm),
close(Stream).
または、あなたはそれらの年齢でソートして全ての人のデータを書き出したいとします。
あなたは、次のようにそれをすることができました。
main([AddrBook,Person]) :-
read_xmlfile(AddrBook, Book),
findall(person(Age,Name), getperson(Book, Name, Age), List),
sort(List, SortedList),
writeq(SortedList),
nl.
read_xmlfile(Filename, XmlTerm) :-
open(Filename, read, Stream),
read_xml(Stream, XmlTerm),
close(Stream).
getperson(document(_,Elements,_), Name, Age) :-
member(Element, Elements),
Element = element(address,Attributes,[NameElem,AgeElem]),
AgeElem = element(age,_,[chardata(AgeString)]),
atom_number(AgeString, Age),
NameElem = element(name,_,[chardata(Name)]).
最後の例題は、低レベル項の処理が非常に複雑であることを示しました(getperson/2を参照します)。
したがって、MINERVAは低レベルのXML項をより便利なフォーマットに変換するための若干の述語を提供します。 これらの述語を使うことにより、最後の例題は以下のように実装されました。
main([AddrBook,Person]) :-
read_xmlfile(AddrBook, XmlTerm),
booktype(BookType),
xmldoc2term(BookType, XmlTerm, Book),
findall(person(Age,Name), getperson(Book, Name, Age), List),
sort(List, SortedList),
writeq(SortedList),
nl.
booktype(addressbook(any * AddressType)) :-
AddressType = address(
telno=atom, % Attribute 'telno'
email=opt(atom,''), % Optional attribute 'email' (defaults to '')
name(-atom),
age(-integer))). % subelements 'name' and 'age'
read_xmlfile(Filename, XmlTerm) :-
open(Filename, read, Stream),
read_xml(Stream, XmlTerm),
close(Stream).
getperson(addressbook(AddressList), Name, Age) :-
member(address(_, _, name(Name), age(Age)), AddressList).
|