Preliminary documentation about ProXML v1.0

Mark Huckvale (mark@phonetics.ucl.ac.uk)
Fri, 12 Mar 1999 14:27:06 +0000

--=====================_921248826==_
Content-Type: text/plain; charset="us-ascii"

Please find attached a first attempt at documentation for the
ProXML processing language. It should be sufficient for you to
get a feel for what the language looks like. However it is not
a tutorial.

I will put the code on the FTP site if anyone wants to try it out.
However I am still debugging!

Mark
--=====================_921248826==_
Content-Type: application/rtf; charset="us-ascii"
Content-Disposition: attachment; filename="ProXML1.0.rtf"

{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f16\froman\fcharset238\fprq2 Times New Roman CE;}{\f17\froman\fcharset204\fprq2 Times New Roman Cyr;}
{\f19\froman\fcharset161\fprq2 Times New Roman Greek;}{\f20\froman\fcharset162\fprq2 Times New Roman Tur;}{\f21\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f22\fswiss\fcharset238\fprq2 Arial CE;}{\f23\fswiss\fcharset204\fprq2 Arial Cyr;}
{\f25\fswiss\fcharset161\fprq2 Arial Greek;}{\f26\fswiss\fcharset162\fprq2 Arial Tur;}{\f27\fswiss\fcharset186\fprq2 Arial Baltic;}{\f28\fmodern\fcharset238\fprq1 Courier New CE;}{\f29\fmodern\fcharset204\fprq1 Courier New Cyr;}
{\f31\fmodern\fcharset161\fprq1 Courier New Greek;}{\f32\fmodern\fcharset162\fprq1 Courier New Tur;}{\f33\fmodern\fcharset186\fprq1 Courier New Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;
\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;
\red192\green192\blue192;}{\stylesheet{\nowidctlpar\widctlpar\adjustright \lang2057\cgrid \snext0 Normal;}{\s1\sb240\sa60\keepn\nowidctlpar\widctlpar\adjustright \b\f1\fs28\lang2057\kerning28\cgrid \sbasedon0 \snext0 heading 1;}{
\s2\sb240\sa60\keepn\nowidctlpar\widctlpar\adjustright \b\i\f1\lang2057\cgrid \sbasedon0 \snext0 heading 2;}{\s3\sb240\sa60\keepn\nowidctlpar\widctlpar\adjustright \f1\lang2057\cgrid \sbasedon0 \snext0 heading 3;}{\*\cs10 \additive
Default Paragraph Font;}{\s15\fi-720\li720\nowidctlpar\widctlpar\adjustright \lang2057\cgrid \sbasedon0 \snext15 Indented;}{\*\cs16 \additive \ul\cf2 \sbasedon10 Hyperlink;}{\s17\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid
\sbasedon0 \snext17 Plain Text;}{\s18\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright \lang2057\cgrid \sbasedon0 \snext18 header;}{\s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb
\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid \sbasedon0 \snext19 Code;}{\s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid \sbasedon0 \snext20 Example;}{
\s21\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright \lang2057\cgrid \sbasedon0 \snext21 footer;}}{\*\listtable{\list\listtemplateid67698689\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid15616410}{\list\listtemplateid67698689\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid82263142}{\list\listtemplateid67698689\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid1218126324}}{\*\listoverridetable{\listoverride\listid15616410\listoverridecount0\ls1}{\listoverride\listid82263142\listoverridecount0\ls2}
{\listoverride\listid1218126324\listoverridecount0\ls3}}{\info{\title ProXML - XML Processing Language Version 1}{\author Mark Huckvale}{\operator Mark Huckvale}{\creatim\yr1999\mo3\dy12\hr14\min22}{\revtim\yr1999\mo3\dy12\hr14\min22}
{\printim\yr1999\mo3\dy12\hr11\min56}{\version2}{\edmins1}{\nofpages11}{\nofwords2322}{\nofchars13236}{\*\company Search Systems Ltd}{\nofcharsws16254}{\vern71}}\paperw11909\paperh16834\margl1440\margr1440
\widowctrl\ftnbj\aenddoc\formshade\viewkind4\viewscale100\pgbrdrhead\pgbrdrfoot \fet0\sectd \psz9\linex0\headery709\footery709\colsx709\endnhere\sectdefaultcl {\footer \pard\plain \s21\nowidctlpar\widctlpar\tqc\tx4320\tqr\tx8640\adjustright
\lang2057\cgrid {\tab }{\cgrid0 - }{\field{\*\fldinst {\cgrid0 PAGE }}{\fldrslt {\lang1024\cgrid0 10}}}{\cgrid0 -}{
\par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}
{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8
\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \s1\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel0\adjustright \b\f1\fs28\lang2057\kerning28\cgrid {
ProXML - XML Processing Language Version 1.0
\par Language Reference
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {(Draft: March 1999)
\par
\par }{\b Mark Huckvale
\par University College London
\par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel1\adjustright \b\i\f1\lang2057\cgrid {1. Introduction
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par ProXML is a general purpose processing utility for text files marked up in the Extensible Mark-up Language (XML) f
ormat. Input to the ProXML interpreter is an XML file and a ProXML script. Output is an XML file modified according to the instructions in the script.
\par }{\lang1024 {\shpgrp{\*\shpinst\shpleft1728\shptop148\shpright6912\shpbottom1588\shpfhdr0\shpbxcolumn\shpbypara\shpwr1\shpwrk0\shpfblwtxt0\shpz0\shplid1039{\sp{\sn groupLeft}{\sv 3168}}{\sp{\sn groupTop}{\sv 5616}}{\sp{\sn groupRight}{\sv 8352}}
{\sp{\sn groupBottom}{\sv 7056}}{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}{\sp{\sn dyWrapDistTop}{\sv 91440}}{\sp{\sn dyWrapDistBottom}{\sv 91440}}{\shp{\*\shpinst\shplid1026
{\sp{\sn relLeft}{\sv 3168}}{\sp{\sn relTop}{\sv 6480}}{\sp{\sn relRight}{\sv 4032}}{\sp{\sn relBottom}{\sv 7056}}{\sp{\sn fRelFlipH}{\sv 0}}{\sp{\sn fRelFlipV}{\sv 0}}
{\sp{\sn shapeType}{\sv 114}}{\sp{\sn lTxid}{\sv 65536}}{\sp{\sn hspNext}{\sv 1026}}{\shptxt \pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {XML
\par }}}}{\shp{\*\shpinst\shplid1027{\sp{\sn relLeft}{\sv 4896}}{\sp{\sn relTop}{\sv 6456}}{\sp{\sn relRight}{\sv 6192}}{\sp{\sn relBottom}{\sv 6888}}{\sp{\sn fRelFlipH}{\sv 0}}
{\sp{\sn fRelFlipV}{\sv 0}}{\sp{\sn shapeType}{\sv 109}}{\sp{\sn lTxid}{\sv 262144}}{\sp{\sn hspNext}{\sv 1027}}{\shptxt \pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {ProXML
\par }}}}{\shp{\*\shpinst\shplid1028{\sp{\sn relLeft}{\sv 7200}}{\sp{\sn relTop}{\sv 6480}}{\sp{\sn relRight}{\sv 8064}}{\sp{\sn relBottom}{\sv 7056}}{\sp{\sn fRelFlipH}{\sv 0}}
{\sp{\sn fRelFlipV}{\sv 0}}{\sp{\sn shapeType}{\sv 114}}{\sp{\sn lTxid}{\sv 131072}}{\sp{\sn hspNext}{\sv 1028}}{\shptxt \pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {XML
\par }}}}{\shp{\*\shpinst\shplid1029{\sp{\sn relLeft}{\sv 5040}}{\sp{\sn relTop}{\sv 5616}}{\sp{\sn relRight}{\sv 6048}}{\sp{\sn relBottom}{\sv 6192}}{\sp{\sn fRelFlipH}{\sv 0}}
{\sp{\sn fRelFlipV}{\sv 0}}{\sp{\sn shapeType}{\sv 114}}{\sp{\sn lTxid}{\sv 196608}}{\sp{\sn hspNext}{\sv 1029}}{\shptxt \pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {Script
\par }}}}{\shp{\*\shpinst\shplid1033{\sp{\sn relLeft}{\sv 4176}}{\sp{\sn relTop}{\sv 6624}}{\sp{\sn relRight}{\sv 4752}}{\sp{\sn relBottom}{\sv 6768}}{\sp{\sn fRelFlipH}{\sv 0}}{\sp{\sn fRelFlipV}{\sv 0}}{\sp{\sn shapeType}{\sv 13}}}}
{\shp{\*\shpinst\shplid1034{\sp{\sn relLeft}{\sv 6480}}{\sp{\sn relTop}{\sv 6624}}{\sp{\sn relRight}{\sv 7056}}{\sp{\sn relBottom}{\sv 6768}}{\sp{\sn fRelFlipH}{\sv 0}}{\sp{\sn fRelFlipV}{\sv 0}}{\sp{\sn shapeType}{\sv 13}}}}
{\shp{\*\shpinst\shplid1035{\sp{\sn relLeft}{\sv 5472}}{\sp{\sn relTop}{\sv 6192}}{\sp{\sn relRight}{\sv 5616}}{\sp{\sn relBottom}{\sv 6480}}{\sp{\sn fRelFlipH}{\sv 0}}{\sp{\sn fRelFlipV}{\sv 0}}{\sp{\sn shapeType}{\sv 67}}}}
{\shp{\*\shpinst\shplid1037{\sp{\sn relLeft}{\sv 3168}}{\sp{\sn relTop}{\sv 6048}}{\sp{\sn relRight}{\sv 4032}}{\sp{\sn relBottom}{\sv 6480}}{\sp{\sn fRelFlipH}{\sv 0}}{\sp{\sn fRelFlipV}{\sv 0}}{\sp{\sn shapeType}{\sv 202}}{\sp{\sn lTxid}{\sv 327680}}
{\sp{\sn hspNext}{\sv 1037}}{\sp{\sn fFilled}{\sv 0}}{\sp{\sn fLine}{\sv 0}}{\shptxt \pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {Input
\par }}}}{\shp{\*\shpinst\shplid1038{\sp{\sn relLeft}{\sv 7200}}{\sp{\sn relTop}{\sv 6048}}{\sp{\sn relRight}{\sv 8352}}{\sp{\sn relBottom}{\sv 6480}}{\sp{\sn fRelFlipH}{\sv 0}}
{\sp{\sn fRelFlipV}{\sv 0}}{\sp{\sn shapeType}{\sv 202}}{\sp{\sn lTxid}{\sv 393216}}{\sp{\sn hspNext}{\sv 1038}}{\sp{\sn fFilled}{\sv 0}}{\sp{\sn fLine}{\sv 0}}{\shptxt \pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {Output
\par }}}}}{\shprslt{\*\do\dobxcolumn\dobypara\dodhgt8192\dppolygon\dppolycount4\dpptx0\dppty0\dpptx5184\dppty0\dpptx5184\dppty1440\dpptx0\dppty1440\dpx1728\dpy148\dpxsize5184\dpysize1440
\dpfillfgcr255\dpfillfgcg255\dpfillfgcb255\dpfillbgcr255\dpfillbgcg255\dpfillbgcb255\dpfillpat1\dplinew15\dplinecor0\dplinecog0\dplinecob0}}}}{This document describes the ProXML language which is used to write XML processing scripts. The ProXML
interpreter, called PRX, runs on WIN32 and Unix computing platforms and is available free of charge under the GNU public software licence. See the web page }{\field{\*\fldinst { HYPERLINK http://www.phon.ucl.ac.uk/project/prosynth.htm }{{\*\datafield
00d0c9ea79f9bace118c8200aa004ba90b02000000170000002f00000068007400740070003a002f002f007700770077002e00700068006f006e002e00750063006c002e00610063002e0075006b002f00700072006f006a006500630074002f00700072006f00730079006e00740068002e00680074006d000000e0c9ea79
f9bace118c8200aa004ba90b5e00000068007400740070003a002f002f007700770077002e00700068006f006e002e00750063006c002e00610063002e0075006b002f00700072006f006a006500630074002f00700072006f00730079006e00740068002e00680074006d000000}}}{\fldrslt {\cs16\ul\cf2
http://www.phon.ucl.ac.uk/project/prosynth.htm}}}{ for more details.
\par
\par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel1\adjustright \b\i\f1\lang2057\cgrid {2. Overview
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par The ProXML language is a general purpose programming language with some special functionality for working with XML files. Its basic syntax is loosely modelled on 'C', but without much of the complexity of that la
nguage. The particularly novel characteristics of ProXML are:
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li1080\nowidctlpar\widctlpar\jclisttab\tx1080{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls1\adjustright {
Data-driven function calls for each XML element type.
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li1080\nowidctlpar\widctlpar\jclisttab\tx1080{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls1\adjustright {
Polymorphic variables holding characters, integers, floating point numbers and strings.
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li1080\nowidctlpar\widctlpar\jclisttab\tx1080{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls1\adjustright {
Special access to XML attribute values.
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li1080\nowidctlpar\widctlpar\jclisttab\tx1080{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls1\adjustright {Selection o
f XML elements by context
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li1080\nowidctlpar\widctlpar\jclisttab\tx1080{\*\pn \pnlvlblt\ilvl0\ls1\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls1\adjustright {
XML validity checking during operation
\par }\pard \nowidctlpar\widctlpar\adjustright {
\par Here is a simple XML file:
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {
<?xml version='1.0'?>
\par <!DOCTYPE BOOK [
\par <!ELEMENT BOOK (TITLE?, CHAPTER*) >
\par <!ELEMENT CHAPTER (P*) >
\par <!ELEMENT TITLE (#PCDATA) >
\par <!ELEMENT P (#PCDATA) >
\par <!ATTLIST CHAPTER
\par \tab NUM CDATA #IMPLIED >
\par <!ATTLIST P
\par \tab ID CDATA #IMPLIED >
\par ]>
\par <BOOK>
\par <TITLE>This is the title</TITLE>
\par <CHAPTER>
\par <P>This is a paragraph.</P>
\par <P>This is a paragraph.</P>
\par </CHAPTER>
\par <CHAPTER>
\par <P>This is a paragraph.</P>
\par <P>This is a paragraph.</P>
\par </CHAPTER>
\par </BOOK>
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Here is a simple ProXML script that demonstrates some features of the language.
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {
/* intro.prx - number chapters and give paragraphs a unique ID */
\par BOOK \{
\par \tab /* declare a counter variable */
\par \tab var cnt=1;
\par \tab /* declare a node variable */
\par \tab node n;
\par \tab /* repeat for every CHAPTER under BOOK */
\par \tab foreach n (./CHAPTER) \{
\par \tab \tab /* set NUM attribute of chapter */
\par \tab \tab n:NUM = cnt;
\par \tab \tab /* increase counter */
\par \tab \tab cnt += 1;
\par \tab \}
\par \}
\par CHAPTER \{
\par \tab /* declare variable containing number of paragraphs */
\par \tab var num=numchild(.);
\par \tab /* loop over paragraphs */
\par \tab for (var i=1;i<=num;i+=1)
\par \tab \tab /* set ID attribute of P based on
\par \tab \tab NUM attribute of CHAPTER */
\par \tab \tab ./P[i]:ID = :NUM ++ "-" ++ i;
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par In this code the block labelled with 'BOOK' is executed for every BOOK element in the XML file, while th
e block labelled 'CHAPTER' is executed for every CHAPTER element in the file. Normal variables that can hold numbers and strings are declared with the 'var' statement, while node variables which can hold nodes of the parse tree are declared with the 'nod
e
' statement. The 'foreach' statement executes a block of code on each of a set of nodes that match a given pattern, while the 'for' statement executes a block of code a defined number of times. Either statement can be used to walk the parse tree. The bu
ilt-in function 'numchild()' returns the number of direct children of the given node.
\par
\par Here is the output XML file:
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {
<?xml version='1.0'?>
\par <!DOCTYPE BOOK [
\par <!ELEMENT BOOK (TITLE?, CHAPTER*) >
\par <!ELEMENT CHAPTER (P*) >
\par <!ELEMENT TITLE (#PCDATA) >
\par <!ELEMENT P (#PCDATA) >
\par <!ATTLIST CHAPTER
\par \tab NUM CDATA #IMPLIED >
\par <!ATTLIST P
\par \tab ID CDATA #IMPLIED >
\par ]>
\par <BOOK>
\par <TITLE>This is the title</TITLE>
\par <CHAPTER NUM="1">
\par <P ID="1-1">This is a paragraph.</P>
\par <P ID="1-2">This is a paragraph.</P>
\par </CHAPTER>
\par <CHAPTER NUM="2">
\par <P ID="2-1">This is a paragraph.</P>
\par <P ID="2-2">This is a paragraph.</P>
\par </CHAPTER>
\par </BOOK>
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel1\adjustright \b\i\f1\lang2057\cgrid {3. Language Elements
\par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel2\adjustright \f1\lang2057\cgrid {3.1 Procedural Structure
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par There are two types of procedural blocks in ProXML, element procedures and user-defined functions. Element procedures are blocks of code that are executed once per matching element in the XML file, and a declared as
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {<element-list> }{\b \{}{
\par \tab <statement-list>
\par }{\b \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Where <element-list> is a list of element names separated by commas. The system-defined name '.' refers to every element, while '/' refers to the root element. For example:
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {. \{
\par \tab /* process every node */
\par \}
\par / \{
\par \tab /* process root node */
\par \}
\par CHAPTER, TITLE, P \{
\par \tab /* process CHAPTER, TITLE and P elements */
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Element names can appear on more than one procedure.
\par
\par User-defined functions always return a simple variable type, and are declared as:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {\b var}{ <function-name> }{\b (}{ <dummy-argument-list> }{\b )}{ }{\b \{}{
\par \tab <statement-list>
\par }{\b \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Where <dummy-argument-list> is a sequence of pairs of variable type and variable name separated by commas. Variables can
be of type 'var' or type 'node'. 'var' arguments are always passed by value, 'node' variables are always passed by reference. Functions may be recursive, but they must always be declared before they are used. The 'return' statement is used to specify
the value to return. If a function does not contain a return statement (or falls off the end) it returns 0. Functions may also be called as procedures, in which case the return value is ignored.
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {
var average(var v1,var v2,var v3)
\par \{
\par \tab return (v1+v2+v3)/3;
\par \}
\par var numP(node n)
\par \{
\par \tab var cnt=0;
\par \tab var node m;
\par \tab foreach m (n/P) cnt += 1;
\par \tab return cnt;
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel2\adjustright \f1\lang2057\cgrid {3.2 Variables and Expressions
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Normal variables and expressions in ProXML are polymorphic: they automatically change between holding characters, integers, floating-point numbers and strings as required by the context. Thus all of the following have the value 25:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {20+5
\par 5*5
\par "20"+"5"
\par 20+"5"
\par "2"++"5"
\par (1+2)++(2+3)
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par The '++' operator means string concatenation. The built-in functions char(), integer(), float() and string() enforce type conversions if required, for example
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {"test"++char(65)
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par is equal to 'testA'.
\par
\par Normal variables are declared with the 'var' statement, of the form
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {\b var}{ <var-name> ( }{\b =}{ <initial-value> ) \{}{\b ,}{ <var-name> (}{\b =}{ <initial-value>) \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par For example:
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {var counter;

\par var num=1;
\par var n1=1,n2=2;
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Variables can be declared at any point in the procedure in advance of their first use.
\par
\par Node variables are declared with the 'node' statement in an analogous way to normal variables. However node variables cannot be used in
expressions and can only be assigned node values from other node variables. Also node variables can only be tested for equality and inequality. There are a number of built-in node variables:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {. = <current node>
\par .. = <parent of current node>
\par nil = <the empty node>
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Nodes form a strict hierarchy, and ProXML provide means for referring to nodes that dominate a given node or are children of a given node. Thus given some node n, the expressions
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {n/.. = <parent of n>
\par n/P = <first child element of n called P>
\par n/. = <first child element of n>
\par n/.[1] = <first child element of n>
\par n/.[2] = <second child element of n>
\par n/../.[1] = <first child of parent of n>
\par n/./P = <first grandchild element of n called P>
\par n/./P[2] = <second grandchild element of n called P>
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par In norm
al statements, no backtracking is performed to force a match. Thus in the last example, if the first child of n had no child nodes of element type P, the resulting expression would be 'nil' (even if the second child of n did have child nodes of element-t
ype P) . To explicitly search the tree for a pattern, with backtracking on failure, you must use the 'foreach' statement or set up user functions to perform searching.
\par
\par Attribute names can be used explicitly to qualify a node specification. These allow attribute values on nodes to be tested and set. The expression
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {<node-specification> }{\b :}{ <attribute-name>
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par is a normal term consisting of the string value of the given attribute. If the node specification is empty, the current node is taken by default. Thus given this extract of an XML file:
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {
<P ALIGN="LEFT">
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par The following code converts LEFT to RIGHT:
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {P \{
\par \tab if (:ALIGN=="LEFT") :ALIGN="RIGHT";
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Here are other examples
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {:ID = <the ID attribute of the current node>
\par .:ID = <the ID attribute of the current node>
\par ..:ID = <the ID attribute of the parent node>
\par n:ID = <the ID attribute of node n>
\par n/..:ID = < the ID attribute of the parent of node n>
\par n/CHAPTER/TITLE/P:ID = <the ID attribute of a specific node below n >
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Again, remember that this last expression refers to an attribute on a single node, not all nodes that might match this specification.
\par
\par It is also possible to specify element names using an expression rather than a literal, simply by enclosing the expression in parentheses before use. Thus the following identify the same node (the first child of the current node named 'CHAPTER'):
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {./CHAPTER
\par ./CHAPTER[1]
\par ./CHAPTER["1"]
\par ./("CHAPTER")
\par ./("CHAPTER")[1]
\par var c="CHAPTER"; ./(c)
\par ./("CHAP"++"TER")["6"-5]
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par It is not currently possible to identify attributes except through a literal constant.
\par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel2\adjustright \f1\lang2057\cgrid {3.3 Statement Types
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par }{\b Assignment Statement
\par }{
\par The assignment statement sets a variable or an attribute to a given expression, or assigns a node variable to a new node value:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {<variable> }{\b =}{ <expression>;
\par <node> }{\b =}{ <nodevalue>;
\par
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {For example
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {P \{
\par \tab var v;\tab \tab \tab /* declare variable v */
\par \tab node n;\tab \tab \tab /* declare node variable n */
\par \tab v = :ID;\tab \tab /* set v to the current ID attribute */
\par \tab n = ..;\tab \tab \tab /* set n to be the parent of the current node */
\par \tab :ID= n:ID ++ v;\tab /* set the ID attribute from parent and old value */
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Variable assignments may also take these forms which update the current value of the variable:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {<variable> }{\b +=}{ <expression>;
\par <variable> }{\b *=}{ <expression>;
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par These are the same as <variable> = <variable> + <expression>, etc.
\par
\par }{\b If Statement
\par }{
\par The if statement executes a block of statements if a simple expression evaluates as true (non-zero).
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {\b if (}{ <simple-expression> }{\b ) }{
\par }\pard \s20\fi720\li720\nowidctlpar\widctlpar\adjustright {<simple-or-compound-statement>
\par }\pard \s20\nowidctlpar\widctlpar\adjustright {
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {Simple expressions may incorporate the relational operators:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {==\tab equal
\par !=\tab not equal
\par >\tab greater than
\par >=\tab greater than or equal
\par <\tab less than
\par <=\tab less than or equal
\par &&\tab and
\par ||\tab or
\par !\tab not
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par For example
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {BOOK \{

\par \tab var year = :YEAR;
\par \tab if ((1900 < year) && (year <= 2000)) :CENTURY="20";
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par If statements can also include an 'else' block of statements which are executed if the conditional expression evaluates as false (zero).
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {\b if (}{ <simple-expression> }{\b )}{
\par }\pard \s20\fi720\li720\nowidctlpar\widctlpar\adjustright {<simple-or-compound-statement>
\par }\pard \s20\li720\nowidctlpar\widctlpar\adjustright {\b else
\par }\pard \s20\fi720\li720\nowidctlpar\widctlpar\adjustright {<simple-or-compound-statement>
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par For example
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {
var factorial(var n)
\par \{
\par \tab if (n <= 1)
\par \tab \tab return 1;
\par \tab else
\par \tab \tab return n*factorial(n-1);
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par
\par }{\b While statement}{
\par
\par The while statement executes a block of statements while it is the case that some given conditional expressions evaluates as true (non-zero). The syntax is:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {\b while (}{ <simple-expression> }{\b )}{ <simple-or-compound-statement>
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par The conditional expression is of the same format as specified for the 'if' statement. For example:
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {
var log2(var n)
\par \{
\par \tab var cnt=0;
\par \tab var pow2=1;
\par \tab while (pow2 < n) \{
\par \tab \tab pow2 *= 2;
\par \tab \tab cnt += 1;
\par \tab \}
\par \tab return(cnt);
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par
\par }{\b For statement
\par }{
\par The for statement is a convenient means for executing a block of statements a fixed number of times.
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {\b for (}{ <assignment-statement-1> }{\b ;}{ <simple expression> }{\b ;}{ <assignment-statement-2> }{\b )}{ <simple-or-compound-statement>
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Logically, this is just a compact means of writing:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {<assignment-statement-1>
\par }{\b while (}{ <simple-expression> ) }{\b \{}{
\par \tab <simple-or-compound-statement>
\par \tab <assignment-statement-2>
\par }{\b \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par For example:
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {var i;

\par for (i=1;i<=12;i+=1)
\par }\pard \s19\fi720\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 {output(i ++ "\\t" ++ i*i ++ "\\n");

\par }\pard \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 {for (i=1;i<numchild(.);i+=1) \{
\par \tab output(element(./.[i]));
\par \tab output("\\n");
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par
\par }{\b Foreach Statement
\par }{
\par The foreach statement provides a sophisticated mechanism for searching the parse tree to find elements that match a given node specification. The format of the statement is as follows:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {\b foreach}{ <node-variable> }{\b (}{ <node-pattern> }{\b )}{ <simple-or-compound-statement>
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Where node is the name of a node variable which must have been defined previously, node-pattern is a specification of the nodes to be located by their element nam
es, and the statement block specifies the instructions that need to be executed for each matching node. For each match, the node variable is set to the matching element and the block of statements is executed. For example:
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {node n;

\par foreach n (./.) output(element(n)++"\\n");
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Would produce a list of the element names of the children of the current node. Note that in the foreach statement, the underspecified node selector './.' refers to }{\b all}{ children, not just the first one. This is different to the behavi
our in the assignment statement, where
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {node n;

\par n = ./.;
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par sets n to be equal to the first child of the current node only.
\par
\par The node pattern can contain the additional search operator '...' which means 'any number of levels down'. This allows a recursive s
earch down through the tree. In every case, the foreach statement uses backtracking to try to exhaustively find all nodes that match the given pattern. Here is an example of backtracking and the '...' operator. Take the following extract of an XML file
:
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {<CHAPTER>

\par <AUTHOR>Mark</AUTHOR>
\par <TITLE>
\par <P ID=1>The title</P>
\par </TITLE>
\par <P ID=2>A paragraph</P>
\par </CHAPTER>
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par The following node selectors find these nodes:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {CHAPTER/P\tab \tab - finds P ID=2
\par CHAPTER/TITLE/P\tab - finds P ID=1
\par CHAPTER/./P\tab \tab - finds nil
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par However these node patterns, used in the foreach statement, find these nodes:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {CHAPTER/P\tab \tab - finds P ID=2
\par CHAPTER/TITLE/P\tab - finds P ID=1
\par CHAPTER/./P\tab \tab - finds P ID=1
\par CHAPTER/.../P\tab - finds P ID=1 and P ID=2
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par }\pard\plain \s3\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel2\adjustright \f1\lang2057\cgrid {3.4 Built-in functions
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par }{\b var char(var e)
\par }{
\par The char() function converts a variable expression into a single character.
\par
\par }{\b var integer(var e)
\par }{
\par The integer() function converts a variable expression into an integer;
\par
\par }{\b var float(var e)
\par }{
\par The float() function converts a variable expression into a floating-point number.
\par
\par }{\b var string(var e)
\par }{
\par The string() function converts a variable expression into a string;
\par
\par }{\b var numchild(node n)
\par }{
\par The numchild() function returns a count of the number of child nodes directly below the current node.
\par
\par }{\b var element(node n)
\par }{
\par The element() function returns the element name from the supplied node. This provides a simple means for checking the name of a node given a reference to it:
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {P \{
\par \tab if (element(..)=="CHAPTER") output("P in CHAPTER found\\n");
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par }{\b var output(var e)
\par }{
\par The output() function outputs expressions to the standard output. Note that this output can interfere with the XML output if that too is directed to the standard output.
\par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel1\adjustright \b\i\f1\lang2057\cgrid {4. Examples
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Traverse entire tree printing out element names (in indented format)
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {
/* traverse.prx -- ProXML script to traverse entire tree */
\par var report(node n,var depth)
\par \{
\par \tab var\tab i;
\par \tab for (i=1;i<=depth;i+=1) output(" ");
\par \tab output(element(n));
\par \tab output("\\n");
\par \tab var num=numchild(n);
\par \tab for (i=1;i<=num;i+=1) report(n/.[i],depth+1);
\par \}
\par
\par / \{
\par \tab report(.,0);
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Set the ID attribute of each node according to the number of descendants it has
\par
\par }\pard\plain \s19\li720\nowidctlpar\widctlpar\brdrt\brdrsh\brdrs\brdrw20\brsp20 \brdrl\brdrsh\brdrs\brdrw20\brsp80 \brdrb\brdrsh\brdrs\brdrw20\brsp20 \brdrr\brdrsh\brdrs\brdrw20\brsp80 \adjustright \shading1000\cbpat8 \f2\fs16\lang2057\cgrid {
/* descount.prx -- count number of descendants of each node */
\par
\par var numdescendant(node n)
\par \{
\par \tab var num = numchild(n);
\par \tab var cnt = num;
\par \tab for (var i=1;i<=num;i+=1) cnt += numdescendant(n/.[i]);
\par \tab return(cnt);
\par \}
\par
\par . \{
\par \tab :ID = numdescendant(.);
\par \}
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel1\adjustright \b\i\f1\lang2057\cgrid {5. Running the PRX interpreter
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par The ProXML interprter, PRX has the following command line:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {prx (-I) (-o outfile|-O|-n) script.prx *.xml
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par The switches are as follows:
\par
\par \tab -I\tab \tab print the current version number of the PRX interpreter
\par \tab -o }{\i outfile}{\tab Send all XML output to the file }{\i outfile}{
\par \tab -O\tab \tab Send all XML output back into the }{\i same}{ file it came from
\par \tab -n\tab \tab Suppress all XML output, do analysis only.
\par
\par If the input XML filename is just '-', then the XML is read from the standard input channel. In this way, the PRX interpreter can function in a pipeline:
\par
\par }\pard\plain \s20\li720\nowidctlpar\widctlpar\adjustright \f2\fs20\lang2057\cgrid {\tab xmlgenerate }{\b | prx script.prx - |}{ xmldosomething
\par }\pard\plain \s2\sb240\sa60\keepn\nowidctlpar\widctlpar\outlinelevel1\adjustright \b\i\f1\lang2057\cgrid {6. Current Limitations
\par }\pard\plain \nowidctlpar\widctlpar\adjustright \lang2057\cgrid {
\par Functionality to come:
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls3\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls3\adjustright {format() string from arguments

\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls3\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls3\adjustright {
tokenise() string into components
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls3\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls3\adjustright {substring() access
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls3\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls3\adjustright {access to
attributes using expressions for their names
\par }\pard \nowidctlpar\widctlpar\adjustright {
\par Restricted functionality:
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls2\adjustright {
No functionality to insert or delete nodes
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls2\adjustright {No func
tionality to access textual content
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls2\adjustright {
No functionality to read or modify the DTD
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls2\adjustright {
Loads whole XML file into memory before processing
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls2\adjustright {
'Foreach' statement is heavy on stack use: possibly only limited to about 1000 matches.
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls2\adjustright {No global variables
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls2\adjustright {Variable names mus
t be different from element names and attribute names.
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls2\adjustright {
There is no parameter type checking on function arguments.
\par {\pntext\pard\plain\f3\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\nowidctlpar\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls2\adjustright {Huge memory leaks to be plugged

\par }\pard \nowidctlpar\widctlpar\adjustright {
\par }}
--=====================_921248826==_--