Using XML-format files as databases
|
|
Type: | Programming |
Rating: | 3 (intermediate) |
Description: |
The example 'xmlrefexpl.mos' works with a personnel database, retrieving and modifying some of its entries. |
File(s): | booksearch.mos, xmlrefexpl.mos |
Data file(s): | bookexamples.xml, refexample.xml |
|
booksearch.mos |
(!****************************************************** Mosel Example Problems ====================== file booksearch.mos ``````````````````` Retrieving information from an XML database file. (c) 2010 Fair Isaac Corporation author: S.Heipcke, July 2010, rev. Sep 2012 *******************************************************!) model "Search book examples" uses "mmxml" declarations ExampleDB: xmldoc Chapters, Models, Models3, Ratings, Files: list of integer end-declarations ! Read in the XML file load(ExampleDB, "bookexamples.xml") ! **** Get all chapters getnodes(ExampleDB, "/examples/chapter", Chapters) writeln("Chapter titles:\n ", union(c in Chapters) {getattr(ExampleDB, c, "title")}) ! **** Search for all difficult examples (difficulty rating 4 or larger) writeln("Difficult examples:") getnodes(ExampleDB, "/examples/chapter/model/modRating[number()>=4]", Ratings) forall(r in Ratings) do m:=getparent(ExampleDB, r) t:=getnode(ExampleDB, m, "modTitle") writeln(" Example: ", getattr(ExampleDB, m, "id"), " ", getvalue(ExampleDB, t), " (rating: ", getvalue(ExampleDB, r), ")") end-do (! Alternatively: getnodes(ExampleDB, "//model/modRating[number()>=4]/..", Models) forall(e in Models) do t:=getnode(ExampleDB, e, "modTitle") writeln(" Example: ", getattr(ExampleDB, e, "id"), " ", getvalue(ExampleDB, t), " (rating: ", getvalue(ExampleDB, getnode(ExampleDB, e, "modRating")), ")") end-do !) ! **** Search for all model files where "SOS" is mentioned under among features writeln("Models using SOS:") forall(c in Chapters) do getnodes(ExampleDB, c, "model/modFeatures[contains(string(),'SOS')]/../modFile", Files) forall(f in Files) writeln(" File: ", getattr(ExampleDB, c, "directory"), "/", getvalue(ExampleDB, f)) end-do ! **** Search for all examples with several model files writeln("Examples with several model files:") getnodes(ExampleDB, "/examples/chapter/model/modFile[position()=2]/..", Models) forall(e in Models) do getnodes(ExampleDB, e, "modFile[position()>2]", Files) writeln(" Example: ", getattr(ExampleDB, e, "id"), " (", 2+Files.size, " files)") end-do end-model |
xmlrefexpl.mos |
(!****************************************************** Mosel Example Problems ====================== file xmlrefexpl.mos ``````````````````` Example for mmxml ref man. Working with a personnel database of the format: <personnelList> <employee id=""> <startDate> <name> <address> <language> </employee> </personnelList> (c) 2012 Fair Isaac Corporation author: S.Heipcke, Sep. 2012 *******************************************************!) model "xmlref examples" uses "mmxml" declarations DB: xmldoc NodeList, Employees, AllEmployees: list of integer Root, Pers: integer NodeNames: set of string end-declarations ! Reading data from an XML file load(DB, "refexample.xml") ! Set indentation mode for XML output (default after load: MANUAL) setindentmode(DB, XML_AUTO) ! 'getnode' / 'getnodes' ! Get the first element that is not a comment or a processing instruction Root:= getnode(DB,"*") ! Same as: getnode(DB,0,"*") ! Get the name of the employee with attribute id="T345" writeln("**** id='T345': ", getvalue(DB, getnode(DB, "personnelList/region/employee[@id='T345']/name") )) ! Get the 'region' node with id=EMEA EMEA:= getnode(DB, "personnelList/region[@id='EMEA']") ! Check for employee record (node) for 'Sam' under 'EMEA' if getnode(DB, EMEA, "employee/name[string()='Sam']/..")<0 then writeln("No employee called 'Sam' in EMEA") end-if ! List all employees writeln("**** All employees:") getnodes(DB, "personnelList/region/employee", AllEmployees) forall(p in AllEmployees) writeln(textfmt(getvalue(DB, getnode(DB, p, "name")), -10), " (ID: ", getattr(DB,p,"id"), ") region: ", getattr(DB, getparent(DB, p), "id")) ! Get all employees in the Americas getnodes(DB, "personnelList/region[@id='AM']/employee", Employees) writeln("**** Americas employees:") forall(p in Employees) save(DB, p, "") ! All employees who started before 2005 getnodes(DB, "personnelList/region/employee/startDate[number()<2005]/..", Employees) writeln("**** Started before 2005:") forall(p in Employees) save(DB, p, "") ! All employees whose names start with "J" writeln("**** Names starting with 'J':") forall(n in AllEmployees) do getnodes(DB, n, "./name[starts-with(string(),'J')]/..", Employees) forall(p in Employees) save(DB, p, "") end-do ! Employees speaking at least 3 languages (=have a third "language" entry) getnodes(DB, "personnelList/region/employee/language[position()=3]/..", Employees) writeln("**** Speaking at least 3 languages:") forall(p in Employees) save(DB, p, "") ! 'testattr' / 'delattr' ! Switch part-time workers to full-time (delete attribute "parttime") getnodes(DB, "personnelList/region/employee[@parttime]", Employees) writeln("**** Number of part-time workers: ", Employees.size) forall(p in AllEmployees | testattr(DB, p, "parttime")) do writeln(getvalue(DB, getnode(DB, p, "name"))) delattr(DB, p, "parttime") end-do ! 'addnode' ! Add a node to the end of the APAC region personnel list APAC:= getnode(DB, "personnelList/region[@id='APAC']") ! Append a new node to 'APAC' and set its attribute 'id': NewPers:= addnode(DB, APAC, XML_LASTCHILD, XML_ELT, "employee") setattr(DB, NewPers, "id", "T432") ! Create a comment: n:= addnode(DB, NewPers, XML_COM, "This is a new employee") ! Add 2 nodes containing the specified text (nodes): n:= addnode(DB, NewPers, XML_ELT, "startDate", text(2012)) n:= addnode(DB, NewPers, XML_ELT, "name", "Tim") ! Add an empty node, then set its contents: n:= addnode(DB, NewPers, XML_ELT, "address") setvalue(DB, n, "Sydney") ! Add an empty node, then create its contents as a text node: n:= addnode(DB, NewPers, XML_ELT, "language") n:= addnode(DB, n, XML_TXT, "English") writeln("**** Newly added person:") save(DB, NewPers, "") ! save(DB, APAC, "") ! 'getfirstchild' / 'getlastchild' / 'getnext' writeln("**** APAC employees:") Pers:= getfirstchild(DB, APAC) LastPers:= getlastchild(DB, APAC) while(Pers>-1) do if getname(DB, Pers)="employee" then write(" ", getattr(DB,Pers,"id"), ":", getvalue(DB, getnode(DB, Pers, "name"))) end-if if Pers=LastPers then writeln; end-if Pers:= getnext(DB, Pers) end-do ! 'copy' / 'delnode' / 'setvalue' ! Employee Lisa moves to Delhi: ! Retrieve employee record (node) for 'Lisa' Pers:= getnode(DB, "personnelList/region/employee/name[string()='Lisa']/..") ! Copy node, then delete in original location NewPers:= copynode(DB, Pers, DB, APAC, XML_LASTCHILD) delnode(DB, Pers) ! Update the 'address' information setvalue(DB, getnode(DB, NewPers, "address"), "Delhi") writeln("**** After moving:") save(DB, NewPers, "") ! Spacing: * add line in between regions; ! * display three consecutive tags within 'employee' on a single line ! Originally read data has spacing information, newly defined entries all ! need to be set manually -> we redefine spaces for every tag ! New line without indentation for Root setvspace(DB, Root, 1) ! Add extra line in between regions, keeping original indentation getnodes(DB, "personnelList/region", NodeList) forall(r in NodeList) setvspace(DB, r, 2) ! Spacing/indentation for 'employee' tag getnodes(DB, "personnelList/region/employee", Employees) forall(p in Employees) do setvspace(DB, p, 1); sethspace(DB, p, 4) ! Within 'employee', display up to three consecutive tags on a single line getnodes(DB, p, "child::node()[position() mod 3=1]", NodeList) forall(r in NodeList) do setvspace(DB, r, 1); sethspace(DB, r, 6) end-do getnodes(DB, p, "child::node()[position() mod 3<>1]", NodeList) forall(r in NodeList) do setvspace(DB, r, 0); sethspace(DB, r, 1) end-do end-do ! First 'language' starts on a new line and others are printed on the same line getnodes(DB, "personnelList/region/employee/language[position()>=2]", NodeList) forall(r in NodeList) do setvspace(DB, r, 0); sethspace(DB, r, 1) end-do getnodes(DB, "personnelList/region/employee/language[position()=1]", NodeList) forall(r in NodeList) do setvspace(DB, r, 1); sethspace(DB, r, 6) end-do writeln("**** Manual formatting:") ! Set indentation mode to 'manual' to see our own formatting setindentmode(DB, XML_MANUAL) ! save(DB, NewPers, "") save(DB, "") ! 'getname' ! Collect the names of all element nodes occurring in a document: getnodes(DB, "/descendant-or-self::node()", NodeList) NodeNames:= union(r in NodeList | gettype(DB,r)=XML_ELT) {getname(DB,r)} writeln("**** Names of element nodes: ", NodeNames) end-model |
© 2001-2020 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.