Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define xml_init
- //xml_init();
- globalvar
- //object globals
- xml_node,
- xml_doctype,
- xml_declaration,
- xml_document,
- xml_element,
- xml_text,
- //other globals
- xml_debug,
- ;
- //make node objects
- xml_node = object_add();
- xml_doctype = object_add();
- xml_declaration = object_add();
- xml_document = object_add();
- xml_element = object_add();
- xml_text = object_add();
- //define parental relationships on object level
- object_set_parent(xml_doctype , xml_node);
- object_set_parent(xml_declaration , xml_node);
- object_set_parent(xml_document , xml_node);
- object_set_parent(xml_element , xml_node);
- object_set_parent(xml_text , xml_node);
- //other global variables
- xml_debug = 1; // debug: 0 = no messages; 1 = errors; 2 = notices
- return(true);
- #define xml_clear
- //xml_clear([document:id])
- var argument_num;if(!variable_local_exists('argument_count')){var a,i;a=0;for(i=0;i<16;i+=1){if(string(argument[i])!="0"){a=i+1;}}argument_num=a;}else{argument_num=argument_count;}
- // Have all nodes that meet the document requirements (if any) commit suicide
- var document;
- document = false;
- if(argument_num>0){
- document = argument0;
- }
- with(xml_node){
- if(self.document==document || !document){
- //ds_map_destroy(attr_map)
- instance_destroy();
- }
- }
- return(true);
- #define xml_read
- //xml_read(xml:str,[parent:id])
- var argument_num;if(!variable_local_exists('argument_count')){var a,i;a=0;for(i=0;i<16;i+=1){if(string(argument[i])!="0"){a=i+1;}}argument_num=a;}else{argument_num=argument_count;}
- // Read XML as string and convert it to node instances
- var xml,document,parent,
- stack,node,text_node,
- buffer,buffer_start,offset,
- type,name,
- i,c,tag_end,
- closing,autoclose,
- txt,cdata,comment,comments;
- xml = argument0;
- parent = noone;
- if(argument_num>1){
- parent = argument[1];
- }
- //convert tabs to spaces
- xml=string_replace_all(xml,chr(9)," ");
- //clean up leading spaces
- while(string_char_at(xml,1)==" "){
- xml = string_delete(xml,1,1);
- }
- while(string_pos(chr(10)+" ",xml)){
- xml=string_replace_all(xml,chr(10)+" ",chr(10));
- }
- while(string_pos(chr(13)+" ",xml)){
- xml=string_replace_all(xml,chr(13)+" ",chr(13));
- }
- //clean up double spaces
- while(string_pos(" ",xml)){
- xml=string_replace_all(xml," "," ");
- }
- // Set document (no parent = new document)
- if(parent == noone){
- document = xml_node_create(xml_document,"document",noone,self);
- parent = document;
- }else{
- document = parent.document;
- }
- buffer = xml;
- buffer_start = 0;
- stack = ds_stack_create();
- // read contents
- while(str_find(buffer,"<")){
- buffer_start += str_find(buffer,"<");
- buffer = str_after(buffer,"<");
- type = xml_element; // DEFAULT = tag opening
- offset = 0;
- closing = false;
- cdata = "";
- comments = 0;
- switch(string_char_at(buffer,1)){ // Check first character for special node_type
- case "!": // doctype declaration/definition
- type = xml_doctype;
- offset = 1;
- // filter out and capture cdata
- if(string_pos("[CDATA[",buffer)==1){
- cdata = str_between(buffer,"[CDATA[","]]");
- buffer_start += string_length(cdata)+9;
- buffer = str_outside(buffer,"[CDATA[","]]");
- }
- // filter out and capture comments
- while(str_is_first(buffer,"--",">")){
- comment[comments] = str_between(buffer,"--","--");
- buffer_start += string_length(comment[comments])+4;
- buffer = str_outside(buffer,"--","--");
- comments += 1;
- }
- break;
- case "?": // XML declaration
- type = xml_declaration;
- offset = 1;
- break;
- case "/": // tag closing
- closing = true;
- offset = 1;
- break;
- case " ": // whitespace offset
- offset = 1;
- break;
- }
- // determine tag end position
- if(str_is_first(buffer,"/>",">")){
- tag_end = str_find(buffer,"/>");
- autoclose = true;
- }else{
- tag_end = str_find(buffer,">");
- autoclose = false;
- }
- // get name and attributes
- if(str_is_first(buffer," ",tag_end)){
- name = string_lower(str_between(buffer,offset," "));
- attrs = str_between(buffer," ",tag_end);
- }else{
- name = string_lower(str_between(buffer,offset,tag_end));
- attrs = "";
- }
- // create or close the node
- if(!closing){
- // create a node
- node = xml_node_create(type,name,parent,document,attrs);
- node.opentag_start = buffer_start;
- node.opentag_end = buffer_start+tag_end;
- node.closetag_start = buffer_start;
- node.closetag_end = buffer_start+tag_end;
- node.inner_html = "";
- node.outer_html = "";
- if(type == xml_element && !autoclose){ // if it remains opened
- node.node_open = true;
- ds_stack_push(stack,node);
- parent = node;
- if(xml_debug>1)show_debug_message(
- "Pushing node #"+string(node)+" on stack."
- );
- }else{
- node.outer_html = str_between(xml,node.opentag_start-1,node.closetag_end+1);
- }
- if(type==xml_doctype){
- node.cdata = cdata;
- for(i=0;i<comments;i+=1){
- node.comment[i] = comment[i];
- }
- node.comments = comments;
- }
- if(xml_debug>1)show_debug_message(
- "Finished node: name = '"+name+
- "'; attrs = ["+attrs+"]; type = "+string(type)+
- "; open = "+string(node.node_open)+
- "; comments = "+string(comments)
- );
- }else{
- // close a node
- /* Note:
- Variable "name" (name of currently closing tag) is only used to validate.
- The node that's actually closing is the one that was last opened.
- */
- node = ds_stack_pop(stack);
- if(!node){
- if(xml_debug>0)show_debug_message(
- "Malformed XML: closing "+name+" while no tags are open. "
- );
- continue;
- }
- parent = node.parent;
- if(name != node.node_name || !node.node_open){
- if(xml_debug>0)show_debug_message(
- "Malformed XML: closing "+name+" instead of "+node.node_name+". "
- );
- }
- // update node
- node.node_open = false;
- node.closetag_start = buffer_start;
- node.closetag_end = buffer_start+tag_end;
- node.inner_html = str_between(xml,node.opentag_end,node.closetag_start);
- node.outer_html = str_between(xml,node.opentag_start-1,node.closetag_end+1);
- if(xml_debug>1)show_debug_message(
- "Closing element node "+name+":
- from = " + string(node.opentag_start)+", " + string(node.opentag_end)+";
- to = " + string(node.closetag_start)+", " + string(node.closetag_end)
- );
- }
- // make a textnode
- txt = str_between(buffer,">","<"); // grab contents
- c = string_char_at(txt,1);
- while(c==" " || c==chr(10) || c==chr(13)){ // remove leading spaces and newlines
- txt = string_delete(txt,1,1);
- c = string_char_at(txt,1);
- }
- if(txt!=""){ // if not empty, make textnode
- text_node = xml_node_create(xml_text,"text",parent,document);
- text_node.node_value = txt;
- }
- }
- ds_stack_destroy(stack);
- return(document);
- #define xml_node_create
- //xml_node_create(type:obj,name:str,parent:node,document:id,[attrs:str])
- var argument_num;if(!variable_local_exists('argument_count')){var a,i;a=0;for(i=0;i<16;i+=1){if(string(argument[i])!="0"){a=i+1;}}argument_num=a;}else{argument_num=argument_count;}
- // Make a new node
- var node,type,name,parent,document,attrs;
- type = argument0;
- name = argument1;
- parent = argument2;
- document = argument3;
- attrs = "";
- if(argument_num>4){
- attrs = argument[4];
- }
- node = instance_create(0,0,type);
- node.parent = parent;
- node.document = document;
- node.node_name = name;
- node.node_type = type;
- node.child_id = 0;
- node.child_num = 0;
- node.node_open = false;
- node.attr_map = -1;
- if(node.parent && instance_exists(node.parent)){
- node.parent.child_nodes[node.parent.child_num]=node;
- node.parent.child_num+=1;
- node.child_id = node.parent.child_num;
- if(xml_debug>1)show_debug_message(
- "Created node "+string(node)+":
- name="+name+";
- type="+string(type)+";
- parent="+string(parent)+";
- child_id="+string(node.child_id)+";
- attrs="+string(attrs)
- );
- }
- if(type==xml_element && attrs!=""){
- xml_set_attributes(node,attrs);
- }
- if(type==xml_doctype){
- node.doctype_attrs = attrs;
- }
- return(node);
- #define xml_set_attributes
- //xml_set_attributes(node:id,attributes:str)
- // Convert a string with attributes to node variables
- var node,attr,buffer,attrname,attrval,quote;
- node = argument0;
- attr = argument1+" ";
- buffer = attr;
- /*
- if(node.attr_map < 0){
- node.attr_map = ds_map_create();
- }
- */
- do{
- // skip leading whitespaces
- while(string_char_at(buffer,0)==" "){
- buffer = string_delete(buffer,1,1);
- }
- // get attribute name
- if(str_is_first(buffer," ","=")){
- attrname = str_before(buffer," ");
- buffer = str_after(buffer," ");
- has_value = false;
- }else{
- attrname = str_before(buffer,"=");
- buffer = str_after(buffer,"=");
- has_value = true;
- }
- // get attribute value
- quote = '"';
- if(attrname!="" && attrname!=" " && attrname!="/"){
- quote = str_first(buffer,"'",'"'); // determine quote type
- if(str_is_first(buffer,quote," ")){
- attrval = str_between_ext(buffer,quote,quote,0,true,false); // _ext version to allow escaped quotes
- buffer = str_after_ext(buffer,quote,quote,true);
- }else{
- if(has_value){
- attrval = str_before(buffer," ")
- }else{
- attrval = "";
- }
- buffer = str_after(buffer," ");
- }
- with(node){
- variable_local_set("attr_"+attrname,attrval);
- //ds_map_set(attr_map,attrname,attrval);
- if(xml_debug>1)show_debug_message(" - var_set(attr_"+attrname+","+attrval+")");
- }
- }
- //if(!show_question("buffer: "+buffer+"##name: "+attrname+"#val: "+attrval)){return(0)};
- }until(!str_find(buffer," "));
- #define xml_get_attribute
- //xml_get_attribute(element:id,attribute:str)
- var element,attr;
- element = argument0;
- attr = argument1;
- with(element){
- return(var_get("attr_"+attr));
- }
- #define xml_element_select
- //xml_element_select(attribute:str,value:str/real,[num:real])
- var argument_num;if(!variable_local_exists('argument_count')){var a,i;a=0;for(i=0;i<16;i+=1){if(string(argument[i])!="0"){a=i+1;}}argument_num=a;}else{argument_num=argument_count;}
- var attr,val,num,i;
- attr = argument0;
- val = argument1;
- num = 1;
- if(argument_num>2){
- num = max(1,argument[2]);
- }
- i=0;
- with(xml_element){
- if(var_get("attr_"+attr)==val){
- i+=1;
- if(i==num){
- return(id);
- }
- }
- }
- return(false);
- #define xml_element_search
- //xml_element_search(attribute:str,needle:str,[num:real])
- var argument_num;if(!variable_local_exists('argument_count')){var a,i;a=0;for(i=0;i<16;i+=1){if(string(argument[i])!="0"){a=i+1;}}argument_num=a;}else{argument_num=argument_count;}
- var attr,val,num,i;
- attr = argument0;
- val = argument1;
- num = 1;
- if(argument_num>2){
- num = max(1,argument[2]);
- }
- i=0;
- with(xml_element){
- if(string_pos(val,var_get("attr_"+attr))){
- i+=1;
- if(i==num){
- return(id);
- }
- }
- }
- return(false);
- #define xml_is_ancestor
- //xml_is_ancestor(node:id,ancestor:id/str)
- var node,ancestor;
- node = argument0;
- ancestor = argument1;
- with(node){
- if(var_is_local("parent")){
- if(is_string(ancestor)){
- if(node_name==ancestor){
- return(true);
- }
- }else{
- if(parent==ancestor){
- return(true);
- }
- }
- return(xml_is_ancestor(parent,ancestor));
- }
- }
- return(false);
- #define xml_find_ancestor
- //xml_find_ancestor(node:id,ancestor:str)
- var node,ancestor;
- node = argument0;
- ancestor = argument1;
- with(node){
- if(node_name==ancestor){
- return(node);
- }else{
- return(xml_find_ancestor(parent,ancestor));
- }
- }
- return(true);
Add Comment
Please, Sign In to add comment