#include %module XML; sm_string XML_element::data ( Ref xx ) { %x: XML_element; x = xx; %s := case x.xml_element of PCDATA: x.xml_element.data, default: "" end; return s; }; sm_string XML_element::tag ( Ref xx ) { %x: XML_element; x = xx; %s := case x.xml_element of TAG: x.xml_element.tag.name, default: "" end; return s; }; %define concat_string ( x: string, y: string ): string as x+y; void print_XML_element ( Ref e, int tab, bool first_time = false ) { if (e->xml_element.tag == 1) cout << e->xml_element.value.data; else { sm_string name = e->xml_element.value.tag.name; int size = name.size(); cout << "<" << name << ">"; int num = e->xml_element.value.tag.content.cardinality; bool print_tabs = false; for(int i=0; i el = ((Sequence >)(Sequence)(e->xml_element.value.tag.content))[i]; print_XML_element(el,tab+size+2); print_tabs = (el->xml_element.tag != 1); }; if (print_tabs) for(int i=0; ixml_element.value.tag.name << ">"; if (!first_time) cout << endl; }; }; void* print_xml_element ( Ref* e, double* tab ) { print_XML_element(*e,(int) *tab,true); return NULL; }; /* store print_xml_element so it can be used by the interpreter */ static int xml_printer = (store_function("print_xml_element",(void*) &print_xml_element,2,0),0); %define print_element ( e: XML_element ): string as case e.xml_element of PCDATA: e.xml_element.data, TAG: "<" + e.xml_element.tag.name + ">" + reduce( concat_string, "", select list print_element(s) from s in e.xml_element.tag.content ) + "" end; %define tag_projection ( e: list, tag_name: string ): list as select list y from x in e, y in ( case x.xml_element of PCDATA: list(), TAG: if x.xml_element.tag.name = tag_name then x.xml_element.tag.content else list() end ); %define any_projection ( e: list ): list as select list y from x in e, y in ( case x.xml_element of PCDATA: list(), TAG: x.xml_element.tag.content end ); %define wildcard_projection ( e: list ): list as e + ( select list y from x in e, y in ( case x.xml_element of PCDATA: list(), TAG: wildcard_projection(x.xml_element.tag.content) end ) ); %define attribute_projection ( e: list, attr_name: string ): list as select list y from x in e, y in ( case x.xml_element of PCDATA: list(), TAG: select list a.value from a in x.xml_element.tag.attributes where a.name = attr_name end ); %define deref ( idrefs: list ): list as select list e from x in idrefs, y in (case x of IDref: list(x.id_ref), IDrefs: x.id_refs, default: list() end), e in Elements where case e.xml_element of PCDATA: false, TAG: exists a in e.xml_element.tag.attributes: case a.value of ID: a.value.xid=y, default: false end end; %define document ( name: string ): list as select list c from d in Documents, c in d.content where d.name = name;