IF Computer > MINERVA > Manual > Reference > Predicates > XML (eXtended Markup Language) terms

XML (eXtended Markup Language) terms

MINERVA
ifcomputer logo
f
Expert Services on the Web

Minerva supports the manipulation (read/modify/write) of XML terms.

There exist four predicates for reading and writing XML terms.

  • 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

Type definitions for XML terms

The conversion predicates (between highlevel and lowlevel XML terms) need a type description of the XML term, to do their job. The type definition has the following format:

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, ...])

Examples:

The handling of XML terms is easy as you can see from the following example. Suppose you have collected the addresses of your friends in a XML file. This shall have the following format:



    
John 35
Henriette 27

Now you want to read the addressbook in MINERVA. Open the the XML file with open/3 and read the XML term with read_xml/2.

main([XmlFilename]) :-
    open(XmlFilename, read, XmlStream),
    read_xml(XmlStream, XmlTerm),
    close(XmlStream),
    writeq(XmlTerm),
    nl.

When calling this program you will get the following output.

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')])])]),[])

So, you read the XML file and got the content of this file as MINERVA term. You can examine this term, manipulate it and write it back to another file. For example you may have two address books of the same format, one containing the addresses of your friends and the another containing the addresses of your business partners. You may decide to merge the two address books into one book.

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).

Or you want to print all persons sortet by their age. You could do it as follows.

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)]).

The last example showed that the manipulation of lowlevel terms is quite complex (see getperson/2). Therefore MINERVA offers some predicates to convert lowlevel XML terms in a more convenient format. Using these predicates the last example could be implemented as follows.

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).

document: http://www.ifcomputer.co.jp/MINERVA/Manual/Reference/Predicates/XML/print_en.html
published 2008/7/21 update 2001/12/14 (c) 1996-2006 IF Computer Japan
IF Computer 5-28-2 Sendagi, Bunkyo-ku Tel +81-3-5814-3352 info@ifcomputer.com
Customer Support Tokyo 113-0022 Japan   http://www.ifcomputer.com
Back> managed with ubiCMS