11.2 Start Elements

<..ScriptsManager: void startElement(ns, sName, qName, atts)..>
 public void startElement(String ns, String sName,
                         String qName, Attributes atts) {
    <.save status of xmlns above element.>
    <.flag := start new save?.>
    inBody = true;
    String s =  "<" + qName + "\n";
    for(int i=0; i<atts.getLength(); i++ ){
       String name = atts.getQName(i),
              value = atts.getValue(i);
       <.record xmlns.>
       s += " " + name + "=\"" +
          XtpipesUni.toUni(value, "<>&\"") + "\"";
    }
    if( flag ){ <.add missing xmlns attributes.> }
    s += ">" ;
    <.set start element.>
 }
 -_-_-

<..ScriptsManager fields..>
 boolean inBody = false;
 -_-_-

<..flag := start new save?..>
 String key = (atts==null)?
                null
              : (qName + "::" + atts.getValue("class"));
 boolean flag = (key != null) && scripts.containsKey(key);
 
 if( !flag ){
    key = qName;
    flag = scripts.containsKey(key);
 }
 -_-_-

<..set start element..>
 if( flag ){
    Object [] state = { new Boolean(savemode), code, match };
    stack.push( state );
    savemode=true; code=""; match= key;
 } else {
    Object [] state = { new Boolean(savemode), null, null };
    stack.push( state );
 }
 add( s );
 -_-_-

The parsing of an XML string is similar to that of done by a left-to-right bottom up parser of a programming language. Specifically, the token are read and send on to the output stream, until an element whose name appears in the hash table of scripts is encountered. When such an element is encountered, its body is assembled and the corresponding script is applied on the body. The processing might be recursive, in the sense that enclosed elements might also have scripts to process them.

The above applies also to an element name concatenated with its class attribute value, with the substring ‘::’ as a separator.