server-php-xml-class-xquery-lite-class-xquery-lite.php / php
<? //#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
###
// Title : XqueryLite (class_xquery_lite.php) // Version : 0.4 beta // Author : Luis Argerich (lrargerich@yahoo.com) // Last modification date : 05-21-2002 // Description : This is an implementation of a subset of the Xquery // language with intention to add new features in // next releases. It is based on flwr expressions. //#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
###
// History: // 05-21-2002 : First release of this class from my prototype engine // 05-17-2002 : Some changes to solve W3C use-cases //#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
###
// To-Dos: //#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
###
// How to use it: //#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
###
class XqueryLite { var bindings=Array(); function init() { this->bindings=Array(); } function _tokenize(exprs=Array(); level=0; exp," \n\t"); while (// Now see if there's a "{" in the token or a "}" in the token for(i=0;<strlen(tok);tok,level++; } if(substr(i,1)=="}") { level==0) { if(in_array(trim(strtoupper(current)>0) { current; current.=tok = strtok(" \n\t"); } if(strlen(exprs[]=current=exprs; } // This function is the "main" function of the flwr-lite engine, it evaluates a flwr expression // returning an XML fragment as a string. // The function won't be called only for top-level flwr expressions but for inner sub-expressions // recursively as well. function evaluate_xqueryl(result=''; i=0; expr,level=0; i<strlen(chr=='{') { chr=='}') { level>0) && (level>1)) { chr; } if(level==0) { if(strlen(result.=query); } chr<>"{") && (level==0) ){ chr; } chr=substr(i,1); } return // This function returns the root element tagname of an XML // fragment that is later used for auto-adding the root // path to path expressions function _get_root_name(node) { node->node_name(); return // This parses a flwr-lite FOR expression binding and // returns the name of the flwr-lite variable associated // the nodeset is stored in the result_sets array. // A flwr-lite FOR expression can be: // FOR name IN xmlmem( // or // FOR name IN xmldoc( // or // FOR name IN function _parse_for(expr) { tokens=split(" ",name=tokens[2])<>"IN") { trigger_error("Invalid FOR expresion <br/>",E_USER_WARNING); return false; } path=// while the beginning of path is not or document then // queues the function and repeat cosa=substr(path,0,1)<>'path,0,8)<>"document") && (substr(path,path=path=substr(path)); array_unshift(regs[1]); } path,2); parts[0]; parts[1]; // Source maybe xmldoc( // or xmlmem(xml) // or if(substr(xml_source,0,8)=='document') { /* PROCESSING FROM A FILE */ ereg("document\((.*)\)",regs); regs[1]; source); if(!file_exists(name_doc file not found", E_USER_WARNING); } name_doc); //doc->document_element()); //rootname.doc) { trigger_error("XML source document xpath=ctx = result=path); result->nodeset; foreach(f) { if(f="distinct";} this->nodes); } nodes as node->node_type()==XML_ATTRIBUTE_NODE) { node->value; } else { node->dump_node(xpath); unset(cts); unset(xml_source,0,6)=='xmlmem') { /* PROCESSING FROM MEM */ ereg("xmlmem\((.*)\)",regs); regs[1]; source); source,1); // NOTE THAT THE XML STRING MUST BE GLOBAL if(!isset(name_var])) { trigger_error("data=name_var]; if(strlen(doc=xmldoc(rootname=doc->document_element()); //rootname.doc) { trigger_error("XML source was not well formed",E_USER_WARNING); } doc->xpath_init(); doc->xpath_new_context(); ctx->xpath_eval(nodes=functions as f=="distinct-values") {nodes=f(nodeset=Array(); foreach(node) { if(nodeset[]=nodeset[]=node); } } } unset(doc); unset(result); } elseif(substr(') { /* PROCESS FROM A VARIABLE */ //ereg("xmlmem\((.*)\)",regs); xml_source; source,1); this->bindings[data)>0) { data); this->_get_root_name(path='/'.path; if(!name_var was not well formed",E_USER_WARNING); } doc->xpath_init(); doc->xpath_new_context(); ctx->xpath_eval(nodes=functions as f=="distinct-values") {nodes=f(nodeset=Array(); foreach(node) { if(nodeset=nodeset[]=node); } } } unset(doc); unset(result); } else { trigger_error("Invalid xml source <br/>",E_USER_WARNING); return false; } name_of_name=substr(this->result_sets[nodeset; return nodeset) { seen=Array(); nodeset); foreach(node) { this->normalize_elements(normalized,new_nodeset[]=seen[]=cant=count(new_nodeset; } // Normalize can eliminate all the tags // If the node has only one child and it is text then just the text is returned function _normalize_elements(node->node_type()==XML_ATTRIBUTE_NODE) { return data=trim(node)); preg_match_all("/<([^>]*)>[^<]*<\/[^>]*>/",foo); if(count(data=trim(preg_replace("/<.*>(.*)<\/.*>/","$1",node->node_type()==XML_ELEMENT_NODE) { data); data); data); } } return name/xpath_expression // outside a FOR expression so it aways returns a // string, if the xpath expression returned an element // the element is normalized. function _parse_var(norm) { name/expr expr,2); parts[0],1); if(strlen(path="/".data=var_name]; if(strlen(path)>0) { data); this->_get_root_name(path='/'.path; if(!data is not xml ",E_USER_WARNING); } doc->xpath_init(); doc->xpath_new_context(); ctx->xpath_eval(nodes=nodes)>0) { foreach(a_node ) { if(res=a_node); res; } else { if(res=result.=res=a_node); res; } } } } else { result=/* doc=xmldoc(root=doc); if(result=_normalize_elements(<br />"); if(root->node_type()==XML_ATTRIBUTE_NODE) { print("dumping an attribute <br/>"); root->value; } else { root->dump_node( } unset(xpath); unset(result_xp); unset(result; } // This function is very similar to _parse_var BUT // instead of returning the result or the variable // it just counts the number of elements in the nodeset function _count_var(result=''; // If it is a var is parts=explode("/",var_name=substr(parts[1])>0) { parts[1]; } this->bindings[data)==0) { return ''; } if(strlen(doc=xmldoc(rootname=doc->document_element()); rootname.doc) { trigger_error("cannot evaluate a xpath expression because xpath=ctx = result_xp=path); result_xp->nodeset; unset(ctx); unset(doc); return count(result=/* doc=xmldoc(root=doc); if(result=_normalize_elements(<br />"); if(root->node_type()==XML_ATTRIBUTE_NODE) { print("dumping an attribute <br/>"); root->value; } else { root->dump_node( } return result; } // This function parses a flwr-lite where expression returning // true/false depending on the expression value // First flwr variables followed or not by an expression are // evaluated and replaced by their values // then and/or are replaced by &&/|| // then a PHP eval construction is used to eval the expression // :TODO: code this function function _parse_where(result=true; expr); expr,5); wexpr); wexpr); wexpr); if(strstr(wexpr,i=0;<count(counts[1]);cant=counts[1][cosa=i]; cosa,"wexpr); } is_a_var=false; i=0;<strlen(wexpr);chr=substr(i,1); if(") { is_a_var=true; } if(chr,Array(' ',"\t","\n",';',"\n"))) { chr=="[") { chr=="]") { predicate) { if(in_array(is_a_var=false; } } if(!vars[]=a_var=''; } } if(chr<>"a_var.=is_a_var) { a_var; } // Now each variable must be evaluated foreach(exp) { '.ret=exp,1); // And now strreplace ret='"'.wexpr=str_replace(ret,php_code='return('.result=eval(result; } // This function parses a flwr-lite RETURN expression // basically a return expression just contains the word // RETURN followed by another flwr-lite query that can // contain flwr-lite expressions. function _parse_return(expr=ltrim(result=''; // A return expr is expr,6); this->evaluate_xqueryl(sub; } // This function parses a flwr-lite LET expression // a LET statement only binds an evaluation to a variable // name // Let won't normalize path expressions function parse_let(expr=ltrim(name := value expr,4); letexpr); tokens[0]; tokens[1]; var_value); var_name); if(strstr(')) { // We are assigning to a var value //var_value,1); this->_parse_var(var_name=substr(this->bindings[var_value; } function _split_fors(fors=Array(); level=0; for(i<strlen(i++) { expr,chr=="[") { chr=="]") { chr==',') && (afor)>0) { afor; afor.=afor)>0) { afor; fors; } // This function parses a flwr-lite expression // this function is called after filtering out XML constructs from // a flwr-lite query function _parse_query(result=''; this->_tokenize(expr=array_shift(expr=trim(tokens=split(" ",what=trim(what,0,1)=="result.=what,0); } else { switch(strtoupper(multi_fors=expr); if(count(i=count(i>0;afor=ltrim(i]); if(strtoupper(substr(afor='FOR '.afor=rtrim(exprs,expr=name=expr); this->result_sets[nodes as this->bindings[node; exprs); // What follows the FOR expr this->_parse_query(this->_parse_where(query=implode("\n",result.=query); } break; case "RETURN": // If we have a return we parse the return and nothing can follow a return // Theres nothing after a return this->_parse_return(this->parse_let(query=implode("\n",result.=query); break; default: // If we have something else (whitespace I hope) we process what follows // :TODO: cambiar el implode exprs); this->_parse_query(result; } } /* <bib> { for b in xmlmem(b/publisher = "Addison-Wesley" and <book year="{ b/@year }"> { </book> } </bib> '; bib='<bib> <book year="1994"> <title>TCP/IP Illustrated</title> <author><last>Stevens</last><first>W.</first></author> <publisher>Addison-Wesley</publisher> <price> 65.95</price> </book> <book year="1992"> <title>Advanced XML Programming in the Unix environment</title> <author><last>Stevens</last><first>W.</first></author> <publisher>Addison-Wesley</publisher> <price>65.95</price> </book> <book year="2000"> <title>Data on the Web</title> <author><last>Abiteboul</last><first>Serge</first></author> <author><last>Buneman</last><first>Peter</first></author> <author><last>Suciu</last><first>Dan</first></author> <publisher>Morgan Kaufmann Publishers</publisher> <price> 39.95</price> </book> <book year="1999"> <title>The Economics of Technology and Content for Digital TV</title> <editor> <last>Gerbarg</last><first>Darcy</first> <affiliation>CITI</affiliation> </editor> <publisher>Kluwer Academic Publishers</publisher> <price>129.95</price> </book> </bib>'; result=case1); print("Result:<br />"); print("<textarea rows='20' cols='50'></textarea>"); */ ?>
(C) Æliens 20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.