Documention for: rebelxml.r
Created by: reboltof
on: 25-Apr-2006
Last updated by: reboltof on: 28-Apr-2006
Format: text/editable
Downloaded on: 30-Apr-2025
RebelXML - User Manual
Version: 1.2
Date: 28-apr-06
Author: Christophe Coussement (COU)
Contact: reboltof-at-yahoo-dot-com
History:
\table
Date
Version
Description
Author
=row
28-avr-05
1.2
Correct typo (thanks to 10djé !)
COU
=row
27-avr-05
1.1
Add Unit tests examples
COU
=row
25-avr-05
1.0
Initial
COU
/table
\note Warning
RebelXML is currently a BETA version, released in the purpose of getting feedbacks and bugs reports from the users.
Avoid to use this script into a production environnement, as certain key-functionnalities could be changed.
This documentation has no pretention of being complete, and will be reworked as the feedbacks come and the project is being developped.
/note
=== What is RebelXML ?
RebXML is a SAX-like XML access-functions library, which allows the user to read/write/create/delete XML data in a very easy way.
RebXML works directly with the XML data, without the need of any to REBOL block convertion, because it uses the great power of the REBOL parser.
=== What do I need to run RebelXML ?
1. Download the script %RebelXML.r from http://www.rebol.org
2. Be sure you're running REBOL/View >= 1.3 and launch the console
3. Run the script into the console:
do %RebelXML.r
or include it into a script
4. Use the functions described into this document
=== Extracting data from XML data
--- The function 'load-xml-data
USAGE:
LOAD-XML-DATA data
DESCRIPTION:
load xml data into xml-data word
LOAD-XML-DATA is a function value
ARGUMENTS:
data -- XML data to load (Type: string)
--- The function 'get-xml-data
USAGE:
GET-XML-DATA path /content /attribute att-name /with-attribute w-att-name w-att-data
DESCRIPTION:
extract requested data from xml
GET-XML-DATA is a function value.
ARGUMENTS:
path -- the path pointing to the data (Type: path word)
REFINEMENTS:
/content -- if content value is requested
/attribute -- if attribute value is requested
\in
att-name -- name of the attribute (Type: word)
/in
/with-attribute -- qualify a content
\in
w-att-name -- name of the attribute (Type: word)
w-att-data -- value of the attribute (Type: string)
/in
--- Usage example 1: using tags
Let start with this simple example...
Consider this simple XML code example (from http://www.w3schools.com/xml/xml_examples.asp), placed into the file %note.xml:
Tove
Jani
Reminder
Don't forget me this weekend!
And we want to extract the 'to' and 'from' information... Proceed as following:
1. Run the script into the console:
>> do %RebelXML.r
2. Load the XML code into RebelXML:
\note
The XML code must be loaded as a string!
/note
>> load-xml-data read %note.xml
== {
Tove
Jani
Reminder
Don't forget me this weekend!
> get-xml-data/content 'note/to
== ["Tove"]
>> get-xml-data/content 'note/from
== ["Jani"]
Using the /content refinement, you specify to RebelXMl that you are interested into the content of the tag, not anything else. Simple, isn't it ?
--- Usage exemple 2: using attributes
Let's consider the file %note.xml, containing multiple notes, each one identified by an unique identifier 'id':
Tove
Jani
Reminder
Don't forget me this weekend!
Jani
Tove
Re: Reminder
I will not!
We are only interested in the values contained into the note 'p502'. To extract those specific information, we've to specify the required attribute:
>> load-xml-data read %note.xml
== {
Tove
Jani
Reminder
...
>> get-xml-data/content/with-attribute 'messages/note 'id "p502"
== [{
Jani
Tove
Re: Reminder
I will not!
...
If we are searching for more specific information, let's say the field 'to', we've to proceed in 2 requests:
>> load-xml-data read %note.xml
== {
Tove
Jani
Reminder
...
>> load-xml-data first get-xml-data/content/with-attribute 'messages/note 'id "p502"
== {
Jani
Tove
Re: Reminder
I will not!
...
>> get-xml-data/content 'to
== ["Jani"]
Perhaps do we want to know which id's are available into our XML data ? Let do this:
>> load-xml-data read %note.xml
== {
Tove
Jani
Reminder
...
>> get-xml-data/attribute 'note 'id
== ["p501" "p502"]
=== Creating a XML data from scratch
The base idea is quite simple: if you try to write something at the end of a path wich does not exists yet, RebelXML will construct it for you !
You can use those functions to proceed:
--- The function 'set-xml-data
USAGE:
SET-XML-DATA path /content data /attribute att-name att-value /with-attribute w-att-name w-att-data
DESCRIPTION:
set path, content and/or attribute into xml-data
SET-XML-DATA is a function value.
ARGUMENTS:
path -- access path (Type: word path)
REFINEMENTS:
/content -- set a content
\in
data -- content data (Type: string)
/in
/attribute -- set an attribute
\in
att-name -- attribute name (Type: word)
att-value -- attribute data (Type: string)
/in
/with-attribute -- specify a tag with a given attribute
\in
w-att-name -- name of the attribute (Type: word)
w-att-data -- value of the attribute (Type: string)
/in
--- The function 'clear-xml-data
USAGE:
CLEAR-XML-DATA
DESCRIPTION:
clears existing data into internal cache
CLEAR-XML-DATA is a function value.
--- The function 'show-xml-data
USAGE:
SHOW-XML-DATA
DESCRIPTION:
returns data from internal cache
SHOW-XML-DATA is a function value
--- The function 'set-xml-quote
USAGE:
SET-XML-QUOTE user-quote
DESCRIPTION:
set user quote preference (default is 'simple)
SET-XML-QUOTE is a function value.
ARGUMENTS:
user-quote -- May be 'simple or 'double (Type: word)
--- Usage example
As illustration, let's try to reconstitue the "note" we used in the preceding part of this documentation:
To begin from a healthy base, let's clear the buffer:
>> clear-xml-data
== ""
And add the tags and data we need:
>> set-xml-data/content 'note/body "Don't forget me this weekend!"
== {Don't forget me this weekend!}
>> set-xml-data/content 'note/heading "Reminder"
== {ReminderDon't forget me this weekend!}
>> set-xml-data/content 'note/from "Jani"
== {JaniReminderDon't forget
me this weekend!}
>> set-xml-data/content 'note/to "Tove"
== {ToveJaniReminder
Don't forget me this weekend!}
and we can get the generated content by using 'show-xml-data:
>> show-xml-data
== {ToveJaniReminder
Don't forget me this weekend!}
or, if indented:
{
Tove
Jani
Reminder
Don't forget me this weekend!
}
\note Caution
Because RebelXML is inserting the new tags into the existing data, we need to insert first the last data of the set, if the tag order matters. A way to easily handle this is shown next to this.
/note
We could also use a more "REBOLish" code and write:
>> data: [
[ 'note/to "Tove"
[ 'note/from "Jani"
[ 'note/heading "Reminder"
[ 'note/body "Don't forget me this weekend!"
[ ]
== [
'note/to "Tove"
'note/from "Jani"
'note/heading "Reminder"
'note/body "Don't forget me this weekend!"
]
>> reverse data
== ["Don't forget me this weekend!"
'note/body "Reminder"
'note/heading "Jani"
'note/from "Tove"
'note/to
]
>> foreach [content tag] data [set-xml-data/content tag content]
== {ToveJaniReminder
Don't forget me this weekend!}
=== Modifiying existing XML data
The same 'set-xml-data function can be used for modifying existing contents.
--- Usage example
Let's start from our note:
>> load-xml-data read %note.xml
== {
Tove
Jani
Reminder
Don't forget me this weekend!
> set-xml-data/content 'note/to "Frebus"
== {
Frebus
Jani
Reminder
> probe show-xml-data
{
Frebus
Jani
Reminder
Don't forget me this weekend!
}
=== Supplementary note: Unit test used for script validation
For those who are curious to know what "Test Driven Development" is, here is an example of some tests I used for the validation of the function 'set-xml-data.
\note Note
You will need the %RUn.r script for trying those unit tests. You can find it at: http://www.rebol.org/cgi-bin/cgiwrap/rebol/view-script.r?script=run.r
/note
;========================
;=== UNIT TEST ===
;========================
;=== TASK X2.1 - set-data ===
;===========================================================================
;--- set test context
setup: does [
#include %RebelXML.r
]
;===========================================================================
;--- create new path
test-set-data-1a: does [
assert set-xml-data/content 'result/section/section "test"
]
;---
test-set-data-1b: does [
assert-equal show-xml-data {}
]
;--- complete partial path w
test-set-data-2a: does [
load-xml-data {}
assert set-xml-data/content 'result/section/item/time "20"
]
test-set-data-2b: does [
assert-equal show-xml-data {}
]
;---
test-set-data-3a: does [
assert set-xml-data/content 'result/section/section/date "26-jan-06"
]
test-set-data-3b: does [
assert-equal show-xml-data {}
]
test-set-data-4a: does [
load-xml-data {}
assert set-xml-data/attribute 'result/section 'ident "20103"
]
test-set-data-4b: does [
assert-equal show-xml-data {}
]
test-set-data-4c: does [
assert set-xml-data/attribute 'result/section 'type "file"
]
test-set-data-4d: does [
assert-equal show-xml-data {}
]
test-set-data-4e: does [
load-xml-data {}
set-xml-quote 'double
assert set-xml-data/attribute 'result/section 'ident "20103"
]
test-set-data-4f: does [
assert-equal show-xml-data {}
]
test-set-data-5a: does [
load-xml-data {}
set-xml-quote 'simple
assert set-xml-data/content/with-attribute 'result/section "test" 'ident "20104"
]
test-set-data-5b: does [
assert-equal show-xml-data {}
]
test-set-data-6a: does [
load-xml-data {test content}
assert set-xml-data/content 'result/section "new content"
]
test-set-data-6b: does [
assert-equal show-xml-data {test content}
]
;===========================================================================
;--- clean up test context
teardown: does []
;===========================================================================