⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmd.lib.php

📁 完美的在线教育系统
💻 PHP
📖 第 1 页 / 共 3 页
字号:
<?php /*                                                    <!-- xmd.lib.php -->                                                <!-- XML MiniDom, 2006/12/13 --><!-- Copyright (C) 2005 rene.haentjens@UGent.be - see note at end of text    --><!-- Released under the GNU GPL V2, see http://www.gnu.org/licenses/gpl.html -->*//**============================================================================== *	This is the XML Dom library for Dokeos.*	Include/require it in your code to use its functionality.**	@author Rene Haentjens*	@package dokeos.library============================================================================== */class xmddoc{ /* This MiniDom for XML essentially implements an array of elements, each    with a parent, a name, a namespace-URI, attributes & namespace definitions,    and children. Child nodes are a mix of texts and subelements. Parent     and subelements are stored as elementnumbers, the root is element 0.        Parsing is built on James Clark's expat, by default enabled in PHP.        The MiniDom is an alternative to the experimental DOM XML functions.     It is open source PHP and requires no extra libraries.    Restrictions of the MiniDom:    - no two attributes with same name (different namespaces) on one element;    - only 'ISO-8859-1' right now; author will investigate 'UTF-8' later;    - processing instructions & external entities are ignored;    - no distinction between text and cdata child nodes;    - xmd_xml(nonrootelement) may not generate all needed namespace definitions;    - xmd_value, xmd_html_value, xmd_select_xxx, xmd_update, xmd_update_many:      path parameter uses names without namespaces       and supports only a small subset of XPath, with some extensions;    - maximum 11 auto-generated namespace prefixes (can be changed in xmddoc)    Namespace definitions are stored as attributes, with name = 'xmlns...'    e.g. xmlns:xml='http://www.w3.org/XML/1998/namespace'    e.g. xmlns='http://www.imsglobal.org/xsd/imscp_v1p1' (default namespace)        Exposed methods:        new xmddoc(array_of_strings, charset = 'ISO-8859-1'): parse strings    new xmddoc(names, numbers, textstring): restore from cached arrays & string        xmd_add_element(complete_name, parent, attributes_with_complete_names)        complete name = [ URI + ':' + ] name    xmd_set_attribute(element, complete_attribute_name, value) (id. as above)    xmd_add_text(text, element)    xmd_add_text_element(complete_name, text, parent, attributes) =        xmd_add_text(text, xmd_add_element(complete_name, parent, attributes))        xmd_get_element(element) => children, attributes, '?name', '?parent'    xmd_get_ns_uri(element [, attribute_name_without_uri] )        xmd_text(element): combines element and subelements' text nodes    xmd_xml(): generate XML-formatted string (reverse parsing)    xmd_xml(indent_increase, initial_indent, lbr): e.g. '  ', '', "\n"        xmd_value(path): follow path from root, return attribute value or text        e.g. 'manifest/organizations/@default' 'body/p[1]' (1=first, -1=last)    xmd_value(path, parent, fix, function): find value(s) with path from parent,        apply function and decorate with fix = ('pre'=>..., 'in'=>..., 'post')        e.g. 'general/title/*' array('in' => ', ')    extensions to XPath:        -  and  +  for previous and next sibling, e.g. general/title/+/string        -name and +name for sibling with specific name, e.g. item[2]/+item        .. for parent, e.g. general/title/../../technical/format (stops at root)        @* for location (element number within siblings, starts at 1)        @*name for location in siblings with specific name        @. for element name, e.g. organization/*[1]/@.    namespaces are not supported in paths: they use names without URI        xmd_html_value(pathFix, parent, fun): 'path' 'path infix' 'prefix -% path'        'path infix %- postfix': fun = 'htmlspecialchars' by default        xmd_select_elements(path, parent): find element nodes with path (see above)    xmd_select_single_element (id.) returns -1 or elementnumber    xmd_select_elements_where(path, subpath, value, parent): e.g. '@id', '12'        is like XPath with path[@id='12']; subpath = '.' means text    xmd_select_elements_where_notempty(path, subpath, parent): e.g. '@id'    xmd_select_xxx methods only select elements, not attributes        xmd_remove_element(childelement_number)    xmd_remove_nodes(childelement_numbers_and_strings, parent)        xmd_update(path, text, parent): select single element, then:        text element:     replace text by new text        attribute:        give attribute new value = text        somepath/!newtag: create new child element containing text        somepath/~:       delete single (first or only) element    xmd_update_many(paths, subpath, ...): paths can be path1,path2,...:        for all elements selected by all paths, update with subpath        xmd_copy_foreign_child(fdoc, child, parent):        copies fdoc's child as a new child of parent;        note this method hasn't been tested for all cases (namespaces...)        xmd_cache(): dump xmddoc into names+numbers+textstring for serialization        Order of parameters (if present) for xmd_xxx methods:        name, text, children, path, subPath, value,             parent, fix, fun, attributes (name value)            Properties: (G)lobal to xmddoc or array (one for each xmddoc (E)lement)        e.g. $this->name[0] is the name of the document root element    e.g. $this->names[$this->ns[0]] is its namespace URI    e.g. $this->attributes[0]['title'] is the value of its attribute 'title'    e.g. $this->attributes[0]['xmlns:a'] is the URI for prefix 'a:' */        var $names;         //G array: n => namespace URI (0 => '')    var $numbers;       //G array: numeric dump of xmddoc for caching    var $textstring;    //G string: string dump of xmddoc for caching    var $error;         //G string: empty or parsing error message    var $_nesting;      //G array: nested elements while parsing (internal)    var $_ns;           //G array: namespace defs for upcoming element (id.)    var $_concat;       //G bool: concatenate cData with previous (id.)    var $_nsp;          //G array: namespace prefixes in use somewhere (id.)    var $_last;         //G int: last used elementnumber (id.)    var $_strings;      //G int: number of string child nodes cached (id.)        var $parent;        //E int: elementnumber: 0 is root, -1 is parent of root    var $name;          //E string: element name, without namespace    var $ns;            //E int: index into $names to find namespace URI    var $attributes;    //E array: attribute name(without namespace) => value    var $atns;          //E array: attribute name(id.) => index into $names    var $children;      //E array: elementnumbers and strings (text children)            function xmd_get_element($parent = 0)  // for convenience, readonly copy    {        // returns mixed array: children + texts have numeric key,        // other elements are attributes, '?name' and '?parent'                if ($parent < 0 || $parent > $this->_last) return array();                return array_merge($this->children[$parent], $this->attributes[$parent],             array('?name' => $this->name[$parent],                '?parent' => $this->parent[$parent]));    }            function xmd_get_ns_uri($parent = 0, $attName = '')    {        if ($parent < 0 || $parent > $this->_last) return '';                return $attName ? $this->names[$this->atns[$parent][$attName]] :             $this->names[$this->ns[$parent]];    }            function xmd_remove_element($child)  // success = TRUE    {        if ($child <= 0 || $child > $this->_last) return FALSE;                $parent = $this->parent[$child];                foreach ($this->children[$parent] as $key => $value)            if ($value === $child)            {                unset($this->children[$parent][$key]); return TRUE;            }                return FALSE;    }            function xmd_remove_nodes($children, $parent = 0)  // success = TRUE    {        if ($parent < 0 || $parent > $this->_last) return FALSE;                if (!is_array($children)) $children = array($children);                foreach ($children as $child)        {            $childFound = FALSE;            foreach ($this->children[$parent] as $key => $value)                if ($value === $child)                {                    unset($this->children[$parent][$key]);                    $childFound = TRUE; break;                }            if (!$childFound) return FALSE;        }                return TRUE;    }            function xmd_update($xmPath, $text = '', $parent = 0)  // success = TRUE    {        if ($parent < 0 || $parent > $this->_last ||                 !is_string($text) || !is_string($xmPath)) return FALSE;                $m = array();        if (ereg('^(.*)([~!@])(.*)$', $xmPath, $m))  // split on ~ or ! or @        {            $xmPath = $m[1]; $op = $m[2]; $name = $m[3];        }                if (($elem = $this->xmd_select_single_element($xmPath, $parent)) == -1)             return FALSE;            if (isset($op))        {            if     ($op == '!' && $name)            {                $this->xmd_add_text_element($name, $text, $elem); return TRUE;            }            elseif ($op == '@' && $name)            {                $this->attributes[$elem][$name] = $text; return TRUE;            }            elseif ($op == '~' && !$name)                return $this->xmd_remove_element($elem);                    return FALSE;        }                if (($nch = count($this->children[$elem])) > 1) return FALSE;                $this->children[$elem][0] = $text; return TRUE;    }            function xmd_update_many($xmPaths, $subPath = '', $text = '', $parent = 0)    {        $result = TRUE;                foreach (explode(',', $xmPaths) as $xmPath)        foreach ($this->xmd_select_elements($xmPath, $parent) as $elem)            $result &= $this->xmd_update($subPath, $text, $elem);            // '&=' always evaluates rhs, '&&=' skips it if $result is FALSE                return $result;    }        function xmd_copy_foreign_child($fdoc, $fchild = 0, $parent = 0)    {        $my_queue = array($fchild, $parent);  // optimization, see below                while (!is_null($fchild = array_shift($my_queue)))        {            $parent = array_shift($my_queue);                        if (is_string($fchild))                 $this->xmd_add_text($fchild, $parent);                        elseif (isset($fdoc->name[$fchild]))            {                $fullname = $fdoc->name[$fchild];                $attribs = array(); $nsdefs = array();                                if (($nsn = $fdoc->ns[$fchild]))                     $fullname = $fdoc->names[$nsn] . ':' . $fullname;                                foreach ($fdoc->attributes[$fchild] as $name => $value)                {                    if (($p = strrpos($name, ':')) !== FALSE)  // 'xmlns:...'                        $nsdefs[$name] = $value;                                        else                    {                        if (($nsn = $fdoc->atns[$fchild][$name]))                             $name = $fdoc->names[$nsn] . ':' . $name;                        $attribs[$name] = $value;                    }                }                                $child = $this->xmd_add_element($fullname, $parent,                     array_merge($attribs, $nsdefs));                                foreach ($fdoc->children[$fchild] as $ch)                     array_push($my_queue, $ch, $child);                // recursive call was 10 times slower...            }        }    }            function xmd_add_element($name, $parent = 0, $attribs = array())    { 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -