192 lines · 6.8 KB · Text
RawDownload
= xml: XML navigation     include "xml.m";     xml := load Xml Xml->PATH;    Parser, Item, Locator, Attributes, Mark: import xml;        init:   fn(): string;    open: fn(f: string, warning: chan of (Locator, string),                    preelem: string): (ref Parser, string);    fopen: fn(iob: ref Bufio->Iobuf, f: string, warning: chan of (Locator, string),                    preelem: string): (ref Parser, string);        Parser: adt {        fileoffset: int;            next:       fn(p: self ref Parser): ref Item;        down:       fn(p: self ref Parser);        up:         fn(p: self ref Parser);    mark:       fn(p: self ref Parser): ref Mark;        atmark:     fn(p: self ref Parser, m: ref Mark): int;        goto:       fn(p: self ref Parser, m: ref Mark);        str2mark:   fn(p: self ref Parser, s: string): ref Mark;    };        Item: adt {        fileoffset: int;        pick {        Tag =>            name:   string;            attrs:  Attributes;        Text =>            ch:     string;            ws1:   int;              ws2:    int;        Process =>            target: string;            data:   string;        Doctype =>            name:   string;            public: int;            params: list of string;        Stylesheet =>            attrs:  Attributes;        Error =>            loc:    Locator;            msg:    string;        }    };        Locator: adt {        line:       int;        systemid:   string;        publicid:   string;    };        Attribute: adt {        name:       string;        value:      string;    };        Attributes: adt {        all:        fn(a: self Attributes): list of Attribute;        get:        fn(a: self Attributes, name: string): string;    };        Mark: adt {        offset:     int;        str:        fn(m: self ref Mark): string;    }; Xml  provides  an  interface for navigating XML files (`docu‐ments'). Once loaded, the module must first be initialised bycalling  init.   A  new parser instance is created by callingopen(f, warning, preelem), which opens the file f for parsingas  an  XML  document, or fopen(iob, name, warning, preelem),which does the same for an already  open  Iobuf  (the  stringname  will  be used in diagnostics).  Both functions return atuple (p, err).  If there is an error opening the document, pis  nil,  and err contains a description of the error; other‐wise p can be used to examine the contents of  the  document.If  warning  is  not  nil,  non-fatal errors encountered when= parsing will be sent on this channel :  a  separate  processwill be needed to received them. Each error is represented bya tuple (loc, msg), containing  the  location  loc,  and  thedescription,  msg,  of  the  error  encountered. One XML tag,preelem, may be marked  for  special  treatment  by  the  XMLparser:  within  this  tag  all  white  space  will be passedthrough as-is. Once an XML document has been opened,  the  following  Parsermethods may be used to examine the items contained within: p.next()  An XML document is represented by a tree-structure.          Next returns the next item in the document  at  the          current level of the tree within the current parent          element. If  there  are  no  more  such  items,  it          returns nil. p.down()  Down  descends  into the element that has just been          returned by next, which should be a Tag item.  Sub‐          sequent items returned by next will be those within          that tag. p.up()    Up moves up one level in the XML tree. p.mark()  Mark returns a mark that  can  be  used  to  return          later  to the current position in the document. The          underlying file must be seekable for this to work. p.goto(m) Goes back to a previously marked  position,  m,  in          the document. p.atmark(m)          Atmark  returns non-zero if the current position in          the document is the same as that marked by m.   The          current tree level is ignored in the comparison. p.str2mark(s)          Str2mark turns a string as created by Mark.str back          into a mark as returned by Parser.mark.    ItemsVarious species of items live  in  XML  documents;  they  areencapsulated  in  the  Item  adt. This contains one member incommon to all its subtypes: fileoffset, the position  in  theXML  document of the start of the item.  The various kinds ofitem are as follows: Tag    A generic XML tag.  Name  names  the  tag,  and  attrs       holds its attributes, if any. Text   Text represents inline text in the XML document.  With       the exception of text inside the tag named by  preelem       in  open,  any runs of white space are compressed to a       single space, and white space at the start or  end  of       the  text  is elided.  Ch contains the resulting text;       ws1 and ws2 are non-zero if there was originally white       space at the start or end of the text respectively. Process       Process  represents  an XML document processing direc‐       tive.  Target is the processing instruction's  target,       and  data holds the rest of the text inside the direc‐       tive.   XML  stylesheet  directives   are   recognised       directly and have their own item type. Doctype       Doctype should only occur at the start of an xml docu‐       ment, and represents the type of the XML document. Stylesheet       Stylesheet represents  an  XML  stylesheet  processing       request.  The data of the processing request is parsed       as per the RFC into attribute-value pairs. Error  If an unrecoverable error occurs processing the  docu‐       ment,  an  Error item is returned holding the location       (loc), and description (msg) of the error.  This  will       be the last item returned by the parser. The  attribute-value  pairs  in  Tag and Stylesheet items areheld in an Atttributes adt, say a.   A.all()  yields  a  listholding  all  the attributes; a.get(name) yields the value ofthe attribute name. The location returned when  an  error  is  reported  is  heldinside  a  Locator  adt, which holds the line number on whichthe error occurred, the ``system id''  of  the  document  (inthis  implementation,  its file name), and the "public id" ofthe document (not currently used). A Mark m may be converted to  a  string  with  m.str();  thisenables marks to be written out to external storage, to indexa large XML document, for example.  Note that if the XML doc‐ument changes, any stored marks will no longer be valid. == source/appl/lib/xml.b == see ALSO``Extensible  Markup  Language  (XML) 1.0 (Second Edition)'',http://www.w3.org/TR/REC-xml ``Navigating Large XML Documents on Small Devices'' in Volume2. == bugsXML's definition makes it tricky to handle leading and trail‐ing white space efficiently; ws1 and ws2 in Item.Text is  thecurrent compromise.