Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

XRX/Dictionary Editor

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

Motivation You want a simple application that saves one XML file per form. You want multiple users to each be editing individual records without conflict. Design We will put each term in a separate XML file, and the files will be numbered sequentially - 1.xml, 2.xml, and so on. Each file defines a single term, its acronym, and its definition. Method Create a new eXist collection (aka Folder if you are using a WebDAV tool) called "dictionary" Create three collections called "data", "edit", and "views" within the "dictionary" collection. data/1.xml <Term> <id>1</id> <TermName>Hello</TermName> <TermDefinition>An informal greeting.</TermDefinition> </Term> data/2.xml <Term> <id>2</id> <TermName>Howdy</TermName> <TermDefinition>An informal greeting used by cowboys.</TermDefinition> </Term> Your XForms application loads the data into an instance: <xf:instance src="1.xml"/> You pass the ID number to an XQuery "edit.xq" as a parameter in the URI, "id". "edit.xq" uses the ID parameter as a variable, "$id", to build the form. Contents of edit/edit.xq calling format: edit.xq?id=1 xquery version "1.0"; let $id := request:get-paramter(id, '') return <html> ... <xf:instance src="{$id}.xml"/> <xf:submission method="post" action="save.xq"/> ... </html> Contents of new-instance.xml <Term> <id/> <TermName/> <TermDefinition/> </Term> Contents of save.xq xquery version "1.0"; declare namespace xmldb="http://exist-db.org/xquery/xmldb"; (: this is the collection where we store all the terms, one file per term :) let $collection := '/db/dictionary/data' (: this is where the form "POSTS" documents to this XQuery using the POST method of a submission :) let $term := request:get-data() (: this logs you into the collection :) let $collection := xmldb:collection('/db/dictionary/data', 'mylogin', 'mypassword') (: get the next ID :) let $next-id := doc(concat($collection, 'edit/next-id.xml'))/next-id/text() let $file := concat($next-id, 'xml') (: this creates a new file using the next-id and saves the term into the file :) let $store := store($collection, $file, $term) (: now that the save has been done we can increment the next-id :) let $update := update insert doc("/db/dictionary/edit/next-id.xml")/data/next-id/text() ($next-id + 1) (: now put in the id in the file we just created :) let $update := update insert doc( concat($collection, '/', $file) )/Term/id/text() $next-id <results> <message>{$term/TermName/text(), $term/id/text()} has been saved.</message> </results> Contents of edit/next-id.xml <data> <next-id>3</next-id> </data> Contents of views/list-terms.xq As you save more and more terms, you will want to create a list of them. You can create an XQuery that list all terms. For each term you can include a link to view and edit each term. xquery version "1.0"; let $collection := '/db/dictionary/data' return <html> <head> <title>Listing of Dictionary Terms</title> </head> <body> <h1>Dictionary Terms</h1> <ol>{for $term in collection($collection)/Term let $id := $term/id/text() return <li>{$term/TermName/text()} : {$term/Defintion/text()} <a href="view-term.xq?id={$id}">View</a> <a href="../edit/edit.xq?id={$id}">Edit</a> </li> }</ol> </body> </html> Contents of edit/update.xq xquery version "1.0"; declare namespace xmldb="http://exist-db.org/xquery/xmldb"; (: update.xq :) let $collection := '/db/dictionary/data' (: this is where the form "POSTS" documents to this XQuery using the POST method of a submission :) let $term := request:get-data() (: this logs you into the collection :) let $collection := xmldb:collection('/db/dictionary/data', 'mylogin', 'mypassword') (: get the id out of the posted document :) let $id := $term/id/text() let $file := concat($id, '.xml') (: this saves the new file and overwrites the old one :) let $store := store($collection, $file, $term) <results> <message>{$term/TermName/text(), $term/id/text()} has been updated.</message> </results> edit.xq Header The edit.xq takes parameters from the URI (i.e. in the form "edit.xq?id=2") and either puts a new element in the instance or it puts an existing element in the instance. xquery version "1.0"; declare option exist:serialize "method=html media-type=text/html indent=yes"; let $new := request:get-parameter('new', '') let $id := request:get-parameter('id', '') return (: check for required parameters :) if (not($new or $id)) then <error> <message>Parameter "new" and "id" are both missing. One of these two arguments is required for this web service.</message> </error> else let $server-port := substring-before(request:get-url(), '/exist/rest/db/') let $collection := '/db/dictionary/data' (: put in the appropriate file name :) let $file := if ($new) then ('new-instance.xml') else ( concat( $server-port, '/exist/rest', $collection, '/', $id, '.xml')) return <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ev="http://www.w3.org/2001/xml-events" > <head> <title>Edit Term</title> <xf:model> <!-- this line loads either the new instance or the current data file into the form model --> <xf:instance xmlns="" src="{$file}"/> </xf:model> </head> <body> <xf:output ref="id"> <xf:label>ID:</xf:label> </xf:output > <xf:input ref="TermName" class="TermName"> <xf:label>Term:</xf:label> </xf:input> <xf:textarea ref="TermDefinition" class="TermDefinition"> <xf:label>TermDefinition:</xf:label> </xf:textarea > </body> </html> xforms.css The following file can be linked into the form for formatting. [And which file might that be?] Back: Configuration File Editor • Next: Regular Expression Builder