📄 xmd.lib.php
字号:
if (!is_string($name) || $name == '') return -1; if (($p = strrpos($name, ':')) !== FALSE) // URI + ':' + name if ($p == 0 || $p == strlen($name) - 1) return -1; $child = ($this->_last += 1); $uris = array(); $uri = ''; if ($p) { $uri = substr($name, 0, $p); $name = substr($name, $p + 1); $uris[] = $uri; // check uris after defining all attributes } $this->parent[$child] = $parent; $this->name[$child] = $name; $this->ns[$child] = $uri ? $this->_lookup($uri) : 0; $this->children[$child] = array(); $this->attributes[$child] = array(); $this->atns[$child] = array(); foreach ($attribs as $name => $value) if (($uri = $this->xmd_set_attribute($child, $name, $value, FALSE))) $uris[] = $uri; // check at end, not immediately if ($parent >= 0 && $parent <= $this->_last) $this->children[$parent][] = $child; // link to parent foreach ($uris as $uri) $this->_nsPfx($child, $uri); // find prefix (child and upwards) or create new prefix at root return $child; } function xmd_set_attribute($parent, $name, $value, $checkurihaspfx = TRUE) { if (!is_string($name) || $name == '') return ''; if (($p = strrpos($name, ':')) !== FALSE) // URI + ':' + name if ($p == 0 || $p == strlen($name) - 1) return ''; $uri = ''; // beware of 'xmlns...', which is a namespace def! if ($p) if (substr($name, 0, 6) != 'xmlns:') { $uri = substr($name, 0, $p); $name = substr($name, $p + 1); } $this->attributes[$parent][$name] = $value; $this->atns[$parent][$name] = $uri ? $this->_lookup($uri) : 0; if ($checkurihaspfx) if ($uri) $this->_nsPfx($parent, $uri); if (substr($name, 0, 6) == 'xmlns:') // namespace def with prefix $this->_nsp[substr($name, 6)] = $value; // prefix is in use return $uri; } function xmd_add_text($text, $parent = 0) // success = TRUE { if ($parent < 0 || $parent > $this->_last || !is_string($text)) return FALSE; if ($text) $this->children[$parent][] = $text; return TRUE; } function xmd_add_text_element($name, $text, $parent = 0, $attribs = array()) { $this->xmd_add_text($text, $child = $this->xmd_add_element($name, $parent, $attribs)); return $child; } function xmd_text($parent = 0) { if ($parent < 0 || $parent > $this->_last) return ''; $text = ''; // assemble text subnodes and text in child elements foreach ($this->children[$parent] as $child) $text .= is_string($child) ? $child : $this->xmd_text($child); return $text; } function xmd_xml($increase = ' ', $indent = '', $lbr = "\n", $parent = 0) { if ($parent < 0 || $parent > $this->_last) return ''; $uri = $this->names[$this->ns[$parent]]; $pfxc = ($uri == '') ? '' : $this->_nsPfx($parent, $uri); $dbg = ''; // ($uri == '') ? '' : (' <!-- ' . $uri . ' -->'); $result = $indent . '<' . ($element = $pfxc . $this->name[$parent]); $atnsp = $this->atns[$parent]; foreach ($this->attributes[$parent] as $name => $value) { if (isset($atnsp[$name])) $atnsn = $atnsp[$name]; elseif (isset($atnsn)) unset($atnsn); $uri = isset($atnsn) && isset($this->names[$atnsn]) ? $this->names[$atnsn] : ''; $pfxc = ($uri == '') ? '' : $this->_nsPfx($parent, $uri); $result .= ' ' . $pfxc . $name . '="' . htmlspecialchars($value) . '"'; } if (count($this->children[$parent]) == 0) return $result . ' />' . $dbg; $result .= '>'; foreach ($this->children[$parent] as $child) $result .= is_string($child) ? htmlspecialchars($child) : ($lbr . $this->xmd_xml($increase, $indent.$increase, $lbr, $child)); if (!is_string($child)) $result .= $lbr . $indent; // last $child return $result . '</' . $element . '>' . $dbg; } function xmd_value($xmPath, $parent = 0, $fix = array(), $fun = '') { // extensions: @*[name] for element position (starts at 1) // @. for element (tag)name if ($parent < 0 || $parent > $this->_last || !is_string($xmPath)) return ''; if (($p = strrpos($xmPath, '@')) !== FALSE) { $attName = substr($xmPath, $p+1); $xmPath = substr($xmPath, 0, $p); } if (!($elems = $this->xmd_select_elements($xmPath, $parent))) return ''; $result = ''; $fixin = isset($fix['in']) ? $fix['in'] : ''; foreach ($elems as $elem) { $value = isset($attName) && strlen($attName) >= 1 ? ($attName == '.' ? $this->name[$elem] : ($attName{0} == '*' ? $this->_sibnum($elem, substr($attName, 1)) : $this->attributes[$elem][$attName])) : $this->xmd_text($elem); $result .= $fixin . ($fun ? $fun($value) : $value); } return (isset($fix['pre']) ? $fix['pre'] : '') . substr($result, strlen($fixin)) . (isset($fix['post']) ? $fix['post'] : ''); } function xmd_html_value($xmPath, $parent = 0, $fun = 'htmlspecialchars') { if (!is_string($xmPath)) return ''; $fix = array(); if (($p = strpos($xmPath, ' -% ')) !== FALSE) { $fix['pre'] = substr($xmPath, 0, $p); $xmPath = substr($xmPath, $p+4); } if (($p = strpos($xmPath, ' %- ')) !== FALSE) { $fix['post'] = substr($xmPath, $p+4); $xmPath = substr($xmPath, 0, $p); } if (($p = strpos($xmPath, ' ')) !== FALSE) { $fix['in'] = substr($xmPath, $p+1); $xmPath = substr($xmPath, 0, $p); } return $this->xmd_value($xmPath, $parent, $fix, $fun); } function xmd_select_single_element($xmPath, $parent = 0) // for convenience { $elements = $this->xmd_select_elements($xmPath, $parent); if (count($elements) == 0) return -1; return $elements[0]; } function xmd_select_elements_where($xmPath, $subPath = '.', $value = '', $parent = 0) { if (!is_string($subPath)) return array(); $elems = array(); if ($subPath == '.') $subPath = ''; foreach ($this->xmd_select_elements($xmPath, $parent) as $elem) if ($this->xmd_value($subPath, $elem) == $value) $elems[] = $elem; return $elems; } function xmd_select_elements_where_notempty($xmPath, $subPath = '.', $parent = 0) { if (!is_string($subPath)) return array(); $elems = array(); if ($subPath == '.') $subPath = ''; foreach ($this->xmd_select_elements($xmPath, $parent) as $elem) if ($this->xmd_value($subPath, $elem)) $elems[] = $elem; return $elems; } function xmd_select_elements($xmPath, $parent = 0) { // XPath subset: e1/e2/.../en, also * and e[n] and *[n] (at 1 or -1) // /*/... starts from root, regardless of $parent // extensions: e= - or + (previous & next sibling) // e= -name or +name (sibling of specific name) // e= .. (stops at root, so too many doesn't matter) if (substr($xmPath, 0, 3) == '/*/') { $xmPath = substr($xmPath, 3); $parent = 0; } if ($parent < 0 || $parent > $this->_last) return array(); while (substr($xmPath, 0, 1) == '/') $xmPath = substr($xmPath, 1); while (substr($xmPath, -1) == '/') $xmPath = substr($xmPath, 0, -1); if ($xmPath == '' || $xmPath == '.') return array($parent); if ($xmPath == '..') { if ($parent > 0) return array($this->parent[$parent]); return array($parent); } if ($xmPath{0} == '-' || $xmPath{0} == '+') { $sib = $this->_sibnum($parent, substr($xmPath, 1), $xmPath{0}); if ($sib == -1) return array(); return array($sib); } $m = array(); if (ereg('^(.+)/([^/]+)$', $xmPath, $m)) // split on last / { if (!($set = $this->xmd_select_elements($m[1], $parent))) return $set; // which is empty array if (count($set) == 1) return $this->xmd_select_elements($m[2], $set[0]); $bigset = array(); $m2 = $m[2]; foreach ($set as $e) $bigset = array_merge($bigset, $this->xmd_select_elements($m2, $e)); return $bigset; } $xmName = $xmPath; $xmNum = 0; $elems = array(); if (ereg('^(.+)\[(-?[0-9]+)\]$', $xmPath, $m)) { $xmName = $m[1]; $xmNum = (int) $m[2]; } foreach ($this->children[$parent] as $child) if (!is_string($child)) if ($xmName == '*' || ($this->name[$child]) == $xmName) $elems[] = $child; if ($xmNum == 0) return $elems; $xmNum = ($xmNum > 0) ? $xmNum - 1 : count($elems) + $xmNum; return ($xmNum < count($elems)) ? array($elems[$xmNum]) : array(); } // Notes on parsing and caching:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -