initial commit

This commit is contained in:
Ben Ramey
2017-03-02 21:57:21 -06:00
commit fd8ad64063
22097 changed files with 1960930 additions and 0 deletions

View File

@@ -0,0 +1,221 @@
<?php
#################################################################################
# #
# XML functions #
# written by benjamin ramey #
# bsr@rameydesign.net #
# #
# best viewed with: #
# resolution = 1280x960 #
# tab = 4 spaces #
# indent = 8 spaces #
# #
#################################################################################
##################################################### FUNCTION: xml_parse_file #
# parameters: path to file to parse
# returns: associative array of xml file data
# DOES NOT: handle CDATA, doing anything with WSDL,XSL,namespaces, or numerous
# other cool XML stuff
function xml_parse_file($xml_file)
{
$xml = '';
$data = array();
# first we don't want to waste time, so make sure the file to open exists
if(file_exists($xml_file))
{
# put entire file contents in $xml
$xml = file_get_contents($xml_file);
# if the file is empty, return and error
if(empty($xml)) {
return('XML document is empty.');
}
}
# if the file doesn't exist return an error
else { return("Could not find xml file."); }
# this pattern matches the first line of every xml doc, the <?xml line
$patt = "/^<\?xml([^\?]*)\?>/";
# try to find this mandatory opening <?xml line
if(preg_match($patt,$xml,$matches))
{
# get the xml specs inside the <?xml line
$xml_specs = explode(' ',$matches[1]);
foreach($xml_specs as $spec)
{
# if a spec is empty for some reason, don't attempt to work with it,
# just continue to next one
if(empty($spec)) { continue; }
# specs are always in the name='value' format
list($name,$value) = explode('=',$spec);
# strip away any quotes from the value side of the '='
$value = str_replace("'",'',$value);
$value = str_replace('"','',$value);
# assign these xml specs to the data array
$data[$name] = $value;
}
$xml = substr($xml,strlen($matches[0]));
}
# if we don't find that mandatory opening <?xml line, return an error
else { return('XML document missing opening xml tag.'); }
# xml_left is a heap, initialize with all xml at first
$xml_left = array($xml);
# tmp_refs is also a heap, holding references to points in the xml document
$tmp_refs[] =& $data;
# we will use this pattern to recognize an opening xml tag
$patt = "/^<(\w+)([^>]*)>/";
# we continue through the xml until nothing is left in $xml_left
while(!empty($xml_left))
{
# the last element of $xml_left is always the high priority,
# so process it next
$to_process = array_pop($xml_left);
# trim fore and aft spaces from the xml to process
$to_process = trim($to_process);
# the last index of our tmp_refs array, important later
$last_index = count($tmp_refs) - 1;
# attempt the match the pattern that finds an opening xml tag
if(preg_match($patt,$to_process,$matches)) {
$element = $matches[1];
$parameters = isset($matches[2]) ? $matches[2] : '';
if(isset($tmp_refs[$last_index][$element]))
{
if(is_array($tmp_refs[$last_index][$element]))
{
# case example: [biography]=>[0],[1]...[x]; $element = biography
# endsup: [biography]=>[0],[1]...[x+1]
if(isset($tmp_refs[$last_index][$element][0]))
{
array_push($tmp_refs[$last_index][$element],'');
$tmp_index = count($tmp_refs[$last_index][$element]) - 1;
$tmp_refs[] =& $tmp_refs[$last_index][$element][$tmp_index];
}
# case example: [biography]=>[paragraph]; $element = biography
# endsup: [biography]=>[0]=>[paragraph]
# [1]=>''
else
{
$tmp_ary = $tmp_refs[$last_index][$element];
$tmp_refs[$last_index][$element] = array($tmp_ary,'');
$tmp_refs[] =& $tmp_refs[$last_index][$element][1];
}
}
# case example: [biography]=>"string"; $element = biography
# endsup: [biography]=>[0]=>"string"
# [1]=>''
else
{
$tmp_refs[$last_index][$element] = array($tmp_refs[$last_index][$element],'');
$tmp_refs[] =& $tmp_refs[$last_index][$element][1];
}
}
# case example: [biography]=> NULL; $element = biography
# endsup: [biography]=>""
else
{
$tmp_refs[$last_index][$element] = '';
$tmp_refs[] =& $tmp_refs[$last_index][$element];
}
# if there are parameters, add them as if they were imbedded elements
if(!empty($parameters))
{
$pairs = explode(' ',$parameters);
$last_index = count($tmp_refs) - 1;
# we can do this, because we know the last element added
# is always fresh and new
$tmp_refs[$last_index] = array();
foreach($pairs as $pair)
{
# if a parameter is empty, just continue to next one
if(empty($pair)) { continue; }
list($name,$value) = explode('=',$pair);
$value = str_replace("'",'',$value);
$value = str_replace('"','',$value);
$tmp_refs[$last_index][$name] = $value;
}
}
# we've already found an opening tag, now find the closing tag
$end_tag = strpos($to_process,"</$element>");
# if there is not closing tag--oops! badly formatted xml doc
if($end_tag === FALSE)
{
return("XML document improperly formed.
No closing tag found for element: $element");
}
# get the string length of the opening tag and all the paramters
# inside, plus the opening and closing brackets
$element_len = strlen($matches[0]);
# then, the contents of this xml tag start after the above
# measured length to the end of the $to_process string, minus
# the length of the closing tag
$contents = substr($to_process,$element_len,$end_tag - $element_len);
# if there is text in the $to_process string past this closing
# tag that we just found, put it on top of the $xml_left tag
# it's a sister element of the current one
if($extra = substr($to_process,$end_tag + strlen("</$element>")))
{
array_push($xml_left,$extra);
}
# if not sister elements are found, we are at the end of this
# generation of elements, so place an END indicator in the
# $xml_left array
else
{
array_push($xml_left,'!~~END~~!');
}
array_push($xml_left,$contents);
}
# we place the identifier END to indicate the end of an xml tag that
# has nested tags and no content itself, if this is NOT the case
# we have content to assign the current xml tag
else if($to_process != '!~~END~~!')
{
$tmp_refs[$last_index] = $to_process;
array_pop($tmp_refs);
}
# if we miss the above two ifs, we are at the end of an element
# but don't have content to assign, so step back one generation
# in the xml document
else
{
$tmp = array_pop($tmp_refs);
}
}
# if all went well, we return an associative array with all the xml
# data in it, properly nested
return($data);
}
##################################################### FUNCTION: xml_force_array #
# parameters: path to file to parse
# returns: associative array of xml file data
function xml_force_array($element)
{
$array = array();
if(is_array($element))
{
if(isset($element[0])) { $array = $element; }
else { array_push($array,$element); }
}
else { array_push($array,$element); }
return($array);
}
?>