PageRenderTime 40ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/public/javascripts/jquery/tools/juice/lib/php/PEAR/XML_Util/Util.php

https://github.com/mikeymicrophone/basicblog
PHP | 752 lines | 303 code | 46 blank | 403 comment | 73 complexity | d8da94df3701e71249825a1ac8aa3635 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. <?PHP
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2002 The PHP Group |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license, |
  9. // | that is bundled with this package in the file LICENSE, and is |
  10. // | available at through the world-wide-web at |
  11. // | http://www.php.net/license/2_02.txt. |
  12. // | If you did not receive a copy of the PHP license and are unable to |
  13. // | obtain it through the world-wide-web, please send a note to |
  14. // | license@php.net so we can mail you a copy immediately. |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Stephan Schmidt <schst@php-tools.net> |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Util.php,v 1.28 2006/12/16 09:42:56 schst Exp $
  20. /**
  21. * error code for invalid chars in XML name
  22. */
  23. define("XML_UTIL_ERROR_INVALID_CHARS", 51);
  24. /**
  25. * error code for invalid chars in XML name
  26. */
  27. define("XML_UTIL_ERROR_INVALID_START", 52);
  28. /**
  29. * error code for non-scalar tag content
  30. */
  31. define("XML_UTIL_ERROR_NON_SCALAR_CONTENT", 60);
  32. /**
  33. * error code for missing tag name
  34. */
  35. define("XML_UTIL_ERROR_NO_TAG_NAME", 61);
  36. /**
  37. * replace XML entities
  38. */
  39. define("XML_UTIL_REPLACE_ENTITIES", 1);
  40. /**
  41. * embedd content in a CData Section
  42. */
  43. define("XML_UTIL_CDATA_SECTION", 5);
  44. /**
  45. * do not replace entitites
  46. */
  47. define("XML_UTIL_ENTITIES_NONE", 0);
  48. /**
  49. * replace all XML entitites
  50. * This setting will replace <, >, ", ' and &
  51. */
  52. define("XML_UTIL_ENTITIES_XML", 1);
  53. /**
  54. * replace only required XML entitites
  55. * This setting will replace <, " and &
  56. */
  57. define("XML_UTIL_ENTITIES_XML_REQUIRED", 2);
  58. /**
  59. * replace HTML entitites
  60. * @link http://www.php.net/htmlentities
  61. */
  62. define("XML_UTIL_ENTITIES_HTML", 3);
  63. /**
  64. * Collapse all empty tags.
  65. */
  66. define("XML_UTIL_COLLAPSE_ALL", 1);
  67. /**
  68. * Collapse only empty XHTML tags that have no end tag.
  69. */
  70. define("XML_UTIL_COLLAPSE_XHTML_ONLY", 2);
  71. /**
  72. * utility class for working with XML documents
  73. *
  74. * @category XML
  75. * @package XML_Util
  76. * @version 1.1.0
  77. * @author Stephan Schmidt <schst@php.net>
  78. */
  79. class XML_Util {
  80. /**
  81. * return API version
  82. *
  83. * @access public
  84. * @static
  85. * @return string $version API version
  86. */
  87. function apiVersion()
  88. {
  89. return '1.1';
  90. }
  91. /**
  92. * replace XML entities
  93. *
  94. * With the optional second parameter, you may select, which
  95. * entities should be replaced.
  96. *
  97. * <code>
  98. * require_once 'XML/Util.php';
  99. *
  100. * // replace XML entites:
  101. * $string = XML_Util::replaceEntities("This string contains < & >.");
  102. * </code>
  103. *
  104. * @access public
  105. * @static
  106. * @param string string where XML special chars should be replaced
  107. * @param integer setting for entities in attribute values (one of XML_UTIL_ENTITIES_XML, XML_UTIL_ENTITIES_XML_REQUIRED, XML_UTIL_ENTITIES_HTML)
  108. * @return string string with replaced chars
  109. * @see reverseEntities()
  110. */
  111. function replaceEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML)
  112. {
  113. switch ($replaceEntities) {
  114. case XML_UTIL_ENTITIES_XML:
  115. return strtr($string,array(
  116. '&' => '&amp;',
  117. '>' => '&gt;',
  118. '<' => '&lt;',
  119. '"' => '&quot;',
  120. '\'' => '&apos;' ));
  121. break;
  122. case XML_UTIL_ENTITIES_XML_REQUIRED:
  123. return strtr($string,array(
  124. '&' => '&amp;',
  125. '<' => '&lt;',
  126. '"' => '&quot;' ));
  127. break;
  128. case XML_UTIL_ENTITIES_HTML:
  129. return htmlentities($string);
  130. break;
  131. }
  132. return $string;
  133. }
  134. /**
  135. * reverse XML entities
  136. *
  137. * With the optional second parameter, you may select, which
  138. * entities should be reversed.
  139. *
  140. * <code>
  141. * require_once 'XML/Util.php';
  142. *
  143. * // reverse XML entites:
  144. * $string = XML_Util::reverseEntities("This string contains &lt; &amp; &gt;.");
  145. * </code>
  146. *
  147. * @access public
  148. * @static
  149. * @param string string where XML special chars should be replaced
  150. * @param integer setting for entities in attribute values (one of XML_UTIL_ENTITIES_XML, XML_UTIL_ENTITIES_XML_REQUIRED, XML_UTIL_ENTITIES_HTML)
  151. * @return string string with replaced chars
  152. * @see replaceEntities()
  153. */
  154. function reverseEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML)
  155. {
  156. switch ($replaceEntities) {
  157. case XML_UTIL_ENTITIES_XML:
  158. return strtr($string,array(
  159. '&amp;' => '&',
  160. '&gt;' => '>',
  161. '&lt;' => '<',
  162. '&quot;' => '"',
  163. '&apos;' => '\'' ));
  164. break;
  165. case XML_UTIL_ENTITIES_XML_REQUIRED:
  166. return strtr($string,array(
  167. '&amp;' => '&',
  168. '&lt;' => '<',
  169. '&quot;' => '"' ));
  170. break;
  171. case XML_UTIL_ENTITIES_HTML:
  172. $arr = array_flip(get_html_translation_table(HTML_ENTITIES));
  173. return strtr($string, $arr);
  174. break;
  175. }
  176. return $string;
  177. }
  178. /**
  179. * build an xml declaration
  180. *
  181. * <code>
  182. * require_once 'XML/Util.php';
  183. *
  184. * // get an XML declaration:
  185. * $xmlDecl = XML_Util::getXMLDeclaration("1.0", "UTF-8", true);
  186. * </code>
  187. *
  188. * @access public
  189. * @static
  190. * @param string $version xml version
  191. * @param string $encoding character encoding
  192. * @param boolean $standAlone document is standalone (or not)
  193. * @return string $decl xml declaration
  194. * @uses XML_Util::attributesToString() to serialize the attributes of the XML declaration
  195. */
  196. function getXMLDeclaration($version = "1.0", $encoding = null, $standalone = null)
  197. {
  198. $attributes = array(
  199. "version" => $version,
  200. );
  201. // add encoding
  202. if ($encoding !== null) {
  203. $attributes["encoding"] = $encoding;
  204. }
  205. // add standalone, if specified
  206. if ($standalone !== null) {
  207. $attributes["standalone"] = $standalone ? "yes" : "no";
  208. }
  209. return sprintf("<?xml%s?>", XML_Util::attributesToString($attributes, false));
  210. }
  211. /**
  212. * build a document type declaration
  213. *
  214. * <code>
  215. * require_once 'XML/Util.php';
  216. *
  217. * // get a doctype declaration:
  218. * $xmlDecl = XML_Util::getDocTypeDeclaration("rootTag","myDocType.dtd");
  219. * </code>
  220. *
  221. * @access public
  222. * @static
  223. * @param string $root name of the root tag
  224. * @param string $uri uri of the doctype definition (or array with uri and public id)
  225. * @param string $internalDtd internal dtd entries
  226. * @return string $decl doctype declaration
  227. * @since 0.2
  228. */
  229. function getDocTypeDeclaration($root, $uri = null, $internalDtd = null)
  230. {
  231. if (is_array($uri)) {
  232. $ref = sprintf( ' PUBLIC "%s" "%s"', $uri["id"], $uri["uri"] );
  233. } elseif (!empty($uri)) {
  234. $ref = sprintf( ' SYSTEM "%s"', $uri );
  235. } else {
  236. $ref = "";
  237. }
  238. if (empty($internalDtd)) {
  239. return sprintf("<!DOCTYPE %s%s>", $root, $ref);
  240. } else {
  241. return sprintf("<!DOCTYPE %s%s [\n%s\n]>", $root, $ref, $internalDtd);
  242. }
  243. }
  244. /**
  245. * create string representation of an attribute list
  246. *
  247. * <code>
  248. * require_once 'XML/Util.php';
  249. *
  250. * // build an attribute string
  251. * $att = array(
  252. * "foo" => "bar",
  253. * "argh" => "tomato"
  254. * );
  255. *
  256. * $attList = XML_Util::attributesToString($att);
  257. * </code>
  258. *
  259. * @access public
  260. * @static
  261. * @param array $attributes attribute array
  262. * @param boolean|array $sort sort attribute list alphabetically, may also be an assoc array containing the keys 'sort', 'multiline', 'indent', 'linebreak' and 'entities'
  263. * @param boolean $multiline use linebreaks, if more than one attribute is given
  264. * @param string $indent string used for indentation of multiline attributes
  265. * @param string $linebreak string used for linebreaks of multiline attributes
  266. * @param integer $entities setting for entities in attribute values (one of XML_UTIL_ENTITIES_NONE, XML_UTIL_ENTITIES_XML, XML_UTIL_ENTITIES_XML_REQUIRED, XML_UTIL_ENTITIES_HTML)
  267. * @return string string representation of the attributes
  268. * @uses XML_Util::replaceEntities() to replace XML entities in attribute values
  269. * @todo allow sort also to be an options array
  270. */
  271. function attributesToString($attributes, $sort = true, $multiline = false, $indent = ' ', $linebreak = "\n", $entities = XML_UTIL_ENTITIES_XML)
  272. {
  273. /**
  274. * second parameter may be an array
  275. */
  276. if (is_array($sort)) {
  277. if (isset($sort['multiline'])) {
  278. $multiline = $sort['multiline'];
  279. }
  280. if (isset($sort['indent'])) {
  281. $indent = $sort['indent'];
  282. }
  283. if (isset($sort['linebreak'])) {
  284. $multiline = $sort['linebreak'];
  285. }
  286. if (isset($sort['entities'])) {
  287. $entities = $sort['entities'];
  288. }
  289. if (isset($sort['sort'])) {
  290. $sort = $sort['sort'];
  291. } else {
  292. $sort = true;
  293. }
  294. }
  295. $string = '';
  296. if (is_array($attributes) && !empty($attributes)) {
  297. if ($sort) {
  298. ksort($attributes);
  299. }
  300. if( !$multiline || count($attributes) == 1) {
  301. foreach ($attributes as $key => $value) {
  302. if ($entities != XML_UTIL_ENTITIES_NONE) {
  303. if ($entities === XML_UTIL_CDATA_SECTION) {
  304. $entities = XML_UTIL_ENTITIES_XML;
  305. }
  306. $value = XML_Util::replaceEntities($value, $entities);
  307. }
  308. $string .= ' '.$key.'="'.$value.'"';
  309. }
  310. } else {
  311. $first = true;
  312. foreach ($attributes as $key => $value) {
  313. if ($entities != XML_UTIL_ENTITIES_NONE) {
  314. $value = XML_Util::replaceEntities($value, $entities);
  315. }
  316. if ($first) {
  317. $string .= " ".$key.'="'.$value.'"';
  318. $first = false;
  319. } else {
  320. $string .= $linebreak.$indent.$key.'="'.$value.'"';
  321. }
  322. }
  323. }
  324. }
  325. return $string;
  326. }
  327. /**
  328. * Collapses empty tags.
  329. *
  330. * @access public
  331. * @static
  332. * @param string $xml XML
  333. * @param integer $mode Whether to collapse all empty tags (XML_UTIL_COLLAPSE_ALL) or only XHTML (XML_UTIL_COLLAPSE_XHTML_ONLY) ones.
  334. * @return string $xml XML
  335. */
  336. function collapseEmptyTags($xml, $mode = XML_UTIL_COLLAPSE_ALL) {
  337. if ($mode == XML_UTIL_COLLAPSE_XHTML_ONLY) {
  338. return preg_replace(
  339. '/<(area|base|br|col|hr|img|input|link|meta|param)([^>]*)><\/\\1>/s',
  340. '<\\1\\2 />',
  341. $xml
  342. );
  343. } else {
  344. return preg_replace(
  345. '/<(\w+)([^>]*)><\/\\1>/s',
  346. '<\\1\\2 />',
  347. $xml
  348. );
  349. }
  350. }
  351. /**
  352. * create a tag
  353. *
  354. * This method will call XML_Util::createTagFromArray(), which
  355. * is more flexible.
  356. *
  357. * <code>
  358. * require_once 'XML/Util.php';
  359. *
  360. * // create an XML tag:
  361. * $tag = XML_Util::createTag("myNs:myTag", array("foo" => "bar"), "This is inside the tag", "http://www.w3c.org/myNs#");
  362. * </code>
  363. *
  364. * @access public
  365. * @static
  366. * @param string $qname qualified tagname (including namespace)
  367. * @param array $attributes array containg attributes
  368. * @param mixed $content
  369. * @param string $namespaceUri URI of the namespace
  370. * @param integer $replaceEntities whether to replace XML special chars in content, embedd it in a CData section or none of both
  371. * @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line
  372. * @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column)
  373. * @param string $linebreak string used for linebreaks
  374. * @param boolean $sortAttributes Whether to sort the attributes or not
  375. * @return string $string XML tag
  376. * @see XML_Util::createTagFromArray()
  377. * @uses XML_Util::createTagFromArray() to create the tag
  378. */
  379. function createTag($qname, $attributes = array(), $content = null, $namespaceUri = null, $replaceEntities = XML_UTIL_REPLACE_ENTITIES, $multiline = false, $indent = "_auto", $linebreak = "\n", $sortAttributes = true)
  380. {
  381. $tag = array(
  382. "qname" => $qname,
  383. "attributes" => $attributes
  384. );
  385. // add tag content
  386. if ($content !== null) {
  387. $tag["content"] = $content;
  388. }
  389. // add namespace Uri
  390. if ($namespaceUri !== null) {
  391. $tag["namespaceUri"] = $namespaceUri;
  392. }
  393. return XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $linebreak, $sortAttributes);
  394. }
  395. /**
  396. * create a tag from an array
  397. * this method awaits an array in the following format
  398. * <pre>
  399. * array(
  400. * "qname" => $qname // qualified name of the tag
  401. * "namespace" => $namespace // namespace prefix (optional, if qname is specified or no namespace)
  402. * "localpart" => $localpart, // local part of the tagname (optional, if qname is specified)
  403. * "attributes" => array(), // array containing all attributes (optional)
  404. * "content" => $content, // tag content (optional)
  405. * "namespaceUri" => $namespaceUri // namespaceUri for the given namespace (optional)
  406. * )
  407. * </pre>
  408. *
  409. * <code>
  410. * require_once 'XML/Util.php';
  411. *
  412. * $tag = array(
  413. * "qname" => "foo:bar",
  414. * "namespaceUri" => "http://foo.com",
  415. * "attributes" => array( "key" => "value", "argh" => "fruit&vegetable" ),
  416. * "content" => "I'm inside the tag",
  417. * );
  418. * // creating a tag with qualified name and namespaceUri
  419. * $string = XML_Util::createTagFromArray($tag);
  420. * </code>
  421. *
  422. * @access public
  423. * @static
  424. * @param array $tag tag definition
  425. * @param integer $replaceEntities whether to replace XML special chars in content, embedd it in a CData section or none of both
  426. * @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line
  427. * @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column)
  428. * @param string $linebreak string used for linebreaks
  429. * @param boolean $sortAttributes Whether to sort the attributes or not
  430. * @return string $string XML tag
  431. * @see XML_Util::createTag()
  432. * @uses XML_Util::attributesToString() to serialize the attributes of the tag
  433. * @uses XML_Util::splitQualifiedName() to get local part and namespace of a qualified name
  434. */
  435. function createTagFromArray($tag, $replaceEntities = XML_UTIL_REPLACE_ENTITIES, $multiline = false, $indent = "_auto", $linebreak = "\n", $sortAttributes = true)
  436. {
  437. if (isset($tag['content']) && !is_scalar($tag['content'])) {
  438. return XML_Util::raiseError( 'Supplied non-scalar value as tag content', XML_UTIL_ERROR_NON_SCALAR_CONTENT );
  439. }
  440. if (!isset($tag['qname']) && !isset($tag['localPart'])) {
  441. return XML_Util::raiseError( 'You must either supply a qualified name (qname) or local tag name (localPart).', XML_UTIL_ERROR_NO_TAG_NAME );
  442. }
  443. // if no attributes hav been set, use empty attributes
  444. if (!isset($tag["attributes"]) || !is_array($tag["attributes"])) {
  445. $tag["attributes"] = array();
  446. }
  447. if (isset($tag['namespaces'])) {
  448. foreach ($tag['namespaces'] as $ns => $uri) {
  449. $tag['attributes']['xmlns:'.$ns] = $uri;
  450. }
  451. }
  452. // qualified name is not given
  453. if (!isset($tag["qname"])) {
  454. // check for namespace
  455. if (isset($tag["namespace"]) && !empty($tag["namespace"])) {
  456. $tag["qname"] = $tag["namespace"].":".$tag["localPart"];
  457. } else {
  458. $tag["qname"] = $tag["localPart"];
  459. }
  460. // namespace URI is set, but no namespace
  461. } elseif (isset($tag["namespaceUri"]) && !isset($tag["namespace"])) {
  462. $parts = XML_Util::splitQualifiedName($tag["qname"]);
  463. $tag["localPart"] = $parts["localPart"];
  464. if (isset($parts["namespace"])) {
  465. $tag["namespace"] = $parts["namespace"];
  466. }
  467. }
  468. if (isset($tag["namespaceUri"]) && !empty($tag["namespaceUri"])) {
  469. // is a namespace given
  470. if (isset($tag["namespace"]) && !empty($tag["namespace"])) {
  471. $tag["attributes"]["xmlns:".$tag["namespace"]] = $tag["namespaceUri"];
  472. } else {
  473. // define this Uri as the default namespace
  474. $tag["attributes"]["xmlns"] = $tag["namespaceUri"];
  475. }
  476. }
  477. // check for multiline attributes
  478. if ($multiline === true) {
  479. if ($indent === "_auto") {
  480. $indent = str_repeat(" ", (strlen($tag["qname"])+2));
  481. }
  482. }
  483. // create attribute list
  484. $attList = XML_Util::attributesToString($tag['attributes'], $sortAttributes, $multiline, $indent, $linebreak, $replaceEntities );
  485. if (!isset($tag['content']) || (string)$tag['content'] == '') {
  486. $tag = sprintf('<%s%s />', $tag['qname'], $attList);
  487. } else {
  488. switch ($replaceEntities) {
  489. case XML_UTIL_ENTITIES_NONE:
  490. break;
  491. case XML_UTIL_CDATA_SECTION:
  492. $tag['content'] = XML_Util::createCDataSection($tag['content']);
  493. break;
  494. default:
  495. $tag['content'] = XML_Util::replaceEntities($tag['content'], $replaceEntities);
  496. break;
  497. }
  498. $tag = sprintf('<%s%s>%s</%s>', $tag['qname'], $attList, $tag['content'], $tag['qname'] );
  499. }
  500. return $tag;
  501. }
  502. /**
  503. * create a start element
  504. *
  505. * <code>
  506. * require_once 'XML/Util.php';
  507. *
  508. * // create an XML start element:
  509. * $tag = XML_Util::createStartElement("myNs:myTag", array("foo" => "bar") ,"http://www.w3c.org/myNs#");
  510. * </code>
  511. *
  512. * @access public
  513. * @static
  514. * @param string $qname qualified tagname (including namespace)
  515. * @param array $attributes array containg attributes
  516. * @param string $namespaceUri URI of the namespace
  517. * @param boolean $multiline whether to create a multiline tag where each attribute gets written to a single line
  518. * @param string $indent string used to indent attributes (_auto indents attributes so they start at the same column)
  519. * @param string $linebreak string used for linebreaks
  520. * @param boolean $sortAttributes Whether to sort the attributes or not
  521. * @return string $string XML start element
  522. * @see XML_Util::createEndElement(), XML_Util::createTag()
  523. */
  524. function createStartElement($qname, $attributes = array(), $namespaceUri = null, $multiline = false, $indent = '_auto', $linebreak = "\n", $sortAttributes = true)
  525. {
  526. // if no attributes hav been set, use empty attributes
  527. if (!isset($attributes) || !is_array($attributes)) {
  528. $attributes = array();
  529. }
  530. if ($namespaceUri != null) {
  531. $parts = XML_Util::splitQualifiedName($qname);
  532. }
  533. // check for multiline attributes
  534. if ($multiline === true) {
  535. if ($indent === "_auto") {
  536. $indent = str_repeat(" ", (strlen($qname)+2));
  537. }
  538. }
  539. if ($namespaceUri != null) {
  540. // is a namespace given
  541. if (isset($parts["namespace"]) && !empty($parts["namespace"])) {
  542. $attributes["xmlns:".$parts["namespace"]] = $namespaceUri;
  543. } else {
  544. // define this Uri as the default namespace
  545. $attributes["xmlns"] = $namespaceUri;
  546. }
  547. }
  548. // create attribute list
  549. $attList = XML_Util::attributesToString($attributes, $sortAttributes, $multiline, $indent, $linebreak);
  550. $element = sprintf("<%s%s>", $qname, $attList);
  551. return $element;
  552. }
  553. /**
  554. * create an end element
  555. *
  556. * <code>
  557. * require_once 'XML/Util.php';
  558. *
  559. * // create an XML start element:
  560. * $tag = XML_Util::createEndElement("myNs:myTag");
  561. * </code>
  562. *
  563. * @access public
  564. * @static
  565. * @param string $qname qualified tagname (including namespace)
  566. * @return string $string XML end element
  567. * @see XML_Util::createStartElement(), XML_Util::createTag()
  568. */
  569. function createEndElement($qname)
  570. {
  571. $element = sprintf("</%s>", $qname);
  572. return $element;
  573. }
  574. /**
  575. * create an XML comment
  576. *
  577. * <code>
  578. * require_once 'XML/Util.php';
  579. *
  580. * // create an XML start element:
  581. * $tag = XML_Util::createComment("I am a comment");
  582. * </code>
  583. *
  584. * @access public
  585. * @static
  586. * @param string $content content of the comment
  587. * @return string $comment XML comment
  588. */
  589. function createComment($content)
  590. {
  591. $comment = sprintf("<!-- %s -->", $content);
  592. return $comment;
  593. }
  594. /**
  595. * create a CData section
  596. *
  597. * <code>
  598. * require_once 'XML/Util.php';
  599. *
  600. * // create a CData section
  601. * $tag = XML_Util::createCDataSection("I am content.");
  602. * </code>
  603. *
  604. * @access public
  605. * @static
  606. * @param string $data data of the CData section
  607. * @return string $string CData section with content
  608. */
  609. function createCDataSection($data)
  610. {
  611. return sprintf("<![CDATA[%s]]>", $data);
  612. }
  613. /**
  614. * split qualified name and return namespace and local part
  615. *
  616. * <code>
  617. * require_once 'XML/Util.php';
  618. *
  619. * // split qualified tag
  620. * $parts = XML_Util::splitQualifiedName("xslt:stylesheet");
  621. * </code>
  622. * the returned array will contain two elements:
  623. * <pre>
  624. * array(
  625. * "namespace" => "xslt",
  626. * "localPart" => "stylesheet"
  627. * );
  628. * </pre>
  629. *
  630. * @access public
  631. * @static
  632. * @param string $qname qualified tag name
  633. * @param string $defaultNs default namespace (optional)
  634. * @return array $parts array containing namespace and local part
  635. */
  636. function splitQualifiedName($qname, $defaultNs = null)
  637. {
  638. if (strstr($qname, ':')) {
  639. $tmp = explode(":", $qname);
  640. return array(
  641. "namespace" => $tmp[0],
  642. "localPart" => $tmp[1]
  643. );
  644. }
  645. return array(
  646. "namespace" => $defaultNs,
  647. "localPart" => $qname
  648. );
  649. }
  650. /**
  651. * check, whether string is valid XML name
  652. *
  653. * <p>XML names are used for tagname, attribute names and various
  654. * other, lesser known entities.</p>
  655. * <p>An XML name may only consist of alphanumeric characters,
  656. * dashes, undescores and periods, and has to start with a letter
  657. * or an underscore.
  658. * </p>
  659. *
  660. * <code>
  661. * require_once 'XML/Util.php';
  662. *
  663. * // verify tag name
  664. * $result = XML_Util::isValidName("invalidTag?");
  665. * if (XML_Util::isError($result)) {
  666. * print "Invalid XML name: " . $result->getMessage();
  667. * }
  668. * </code>
  669. *
  670. * @access public
  671. * @static
  672. * @param string $string string that should be checked
  673. * @return mixed $valid true, if string is a valid XML name, PEAR error otherwise
  674. * @todo support for other charsets
  675. */
  676. function isValidName($string)
  677. {
  678. // check for invalid chars
  679. if (!preg_match('/^[[:alpha:]_]$/', $string{0})) {
  680. return XML_Util::raiseError('XML names may only start with letter or underscore', XML_UTIL_ERROR_INVALID_START);
  681. }
  682. // check for invalid chars
  683. if (!preg_match('/^([[:alpha:]_]([[:alnum:]\-\.]*)?:)?[[:alpha:]_]([[:alnum:]\_\-\.]+)?$/', $string)) {
  684. return XML_Util::raiseError('XML names may only contain alphanumeric chars, period, hyphen, colon and underscores', XML_UTIL_ERROR_INVALID_CHARS);
  685. }
  686. // XML name is valid
  687. return true;
  688. }
  689. /**
  690. * replacement for XML_Util::raiseError
  691. *
  692. * Avoids the necessity to always require
  693. * PEAR.php
  694. *
  695. * @access public
  696. * @param string error message
  697. * @param integer error code
  698. * @return object PEAR_Error
  699. */
  700. function raiseError($msg, $code)
  701. {
  702. require_once 'PEAR.php';
  703. return PEAR::raiseError($msg, $code);
  704. }
  705. }
  706. ?>