QPXML.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. /** @file
  3. * XML extensions. See QPXML.
  4. */
  5. /**
  6. * Provide QueryPath with additional XML tools.
  7. *
  8. * @author M Butcher <matt@aleph-null.tv>
  9. * @author Xander Guzman <theshadow@shadowpedia.info>
  10. * @license http://opensource.org/licenses/lgpl-2.1.php LGPL or MIT-like license.
  11. * @see QueryPathExtension
  12. * @see QueryPathExtensionRegistry::extend()
  13. * @see QPXML
  14. * @ingroup querypath_extensions
  15. */
  16. class QPXML implements QueryPathExtension {
  17. protected $qp;
  18. public function __construct(QueryPath $qp) {
  19. $this->qp = $qp;
  20. }
  21. public function schema($file) {
  22. $doc = $this->qp->branch()->top()->get(0)->ownerDocument;
  23. if (!$doc->schemaValidate($file)) {
  24. throw new QueryPathException('Document did not validate against the schema.');
  25. }
  26. }
  27. /**
  28. * Get or set a CDATA section.
  29. *
  30. * If this is given text, it will create a CDATA section in each matched element,
  31. * setting that item's value to $text.
  32. *
  33. * If no parameter is passed in, this will return the first CDATA section that it
  34. * finds in the matched elements.
  35. *
  36. * @param string $text
  37. * The text data to insert into the current matches. If this is NULL, then the first
  38. * CDATA will be returned.
  39. *
  40. * @return mixed
  41. * If $text is not NULL, this will return a {@link QueryPath}. Otherwise, it will
  42. * return a string. If no CDATA is found, this will return NULL.
  43. * @see comment()
  44. * @see QueryPath::text()
  45. * @see QueryPath::html()
  46. */
  47. public function cdata($text = NULL) {
  48. if (isset($text)) {
  49. // Add this text as CDATA in the current elements.
  50. foreach ($this->qp->get() as $element) {
  51. $cdata = $element->ownerDocument->createCDATASection($text);
  52. $element->appendChild($cdata);
  53. }
  54. return $this->qp;;
  55. }
  56. // Look for CDATA sections.
  57. foreach ($this->qp->get() as $ele) {
  58. foreach ($ele->childNodes as $node) {
  59. if ($node->nodeType == XML_CDATA_SECTION_NODE) {
  60. // Return first match.
  61. return $node->textContent;
  62. }
  63. }
  64. }
  65. return NULL;
  66. // Nothing found
  67. }
  68. /**
  69. * Get or set a comment.
  70. *
  71. * This function is used to get or set comments in an XML or HTML document.
  72. * If a $text value is passed in (and is not NULL), then this will add a comment
  73. * (with the value $text) to every match in the set.
  74. *
  75. * If no text is passed in, this will return the first comment in the set of matches.
  76. * If no comments are found, NULL will be returned.
  77. *
  78. * @param string $text
  79. * The text of the comment. If set, a new comment will be created in every item
  80. * wrapped by the current {@link QueryPath}.
  81. * @return mixed
  82. * If $text is set, this will return a {@link QueryPath}. If no text is set, this
  83. * will search for a comment and attempt to return the string value of the first
  84. * comment it finds. If no comment is found, NULL will be returned.
  85. * @see cdata()
  86. */
  87. public function comment($text = NULL) {
  88. if (isset($text)) {
  89. foreach ($this->qp->get() as $element) {
  90. $comment = $element->ownerDocument->createComment($text);
  91. $element->appendChild($comment);
  92. }
  93. return $this->qp;
  94. }
  95. foreach ($this->qp->get() as $ele) {
  96. foreach ($ele->childNodes as $node) {
  97. if ($node->nodeType == XML_COMMENT_NODE) {
  98. // Return first match.
  99. return $node->textContent;
  100. }
  101. }
  102. }
  103. }
  104. /**
  105. * Get or set a processor instruction.
  106. */
  107. public function pi($prefix = NULL, $text = NULL) {
  108. if (isset($text)) {
  109. foreach ($this->qp->get() as $element) {
  110. $comment = $element->ownerDocument->createProcessingInstruction($prefix, $text);
  111. $element->appendChild($comment);
  112. }
  113. return $this->qp;
  114. }
  115. foreach ($this->qp->get() as $ele) {
  116. foreach ($ele->childNodes as $node) {
  117. if ($node->nodeType == XML_PI_NODE) {
  118. if (isset($prefix)) {
  119. if ($node->tagName == $prefix) {
  120. return $node->textContent;
  121. }
  122. }
  123. else {
  124. // Return first match.
  125. return $node->textContent;
  126. }
  127. }
  128. } // foreach
  129. } // foreach
  130. }
  131. public function toXml() {
  132. return $this->qp->document()->saveXml();
  133. }
  134. /**
  135. * Create a NIL element.
  136. *
  137. * @param string $text
  138. * @param string $value
  139. * @reval object $element
  140. */
  141. public function createNilElement($text, $value) {
  142. $value = ($value)? 'true':'false';
  143. $element = $this->qp->createElement($text);
  144. $element->attr('xsi:nil', $value);
  145. return $element;
  146. }
  147. /**
  148. * Create an element with the given namespace.
  149. *
  150. * @param string $text
  151. * @param string $nsUri
  152. * The namespace URI for the given element.
  153. * @retval object
  154. */
  155. public function createElement($text, $nsUri = null) {
  156. if (isset ($text)) {
  157. foreach ($this->qp->get() as $element) {
  158. if ($nsUri === null && strpos($text, ':') !== false) {
  159. $ns = array_shift(explode(':', $text));
  160. $nsUri = $element->ownerDocument->lookupNamespaceURI($ns);
  161. if ($nsUri === null) {
  162. throw new QueryPathException("Undefined namespace for: " . $text);
  163. }
  164. }
  165. $node = null;
  166. if ($nsUri !== null) {
  167. $node = $element->ownerDocument->createElementNS(
  168. $nsUri,
  169. $text
  170. );
  171. } else {
  172. $node = $element->ownerDocument->createElement($text);
  173. }
  174. return qp($node);
  175. }
  176. }
  177. return;
  178. }
  179. /**
  180. * Append an element.
  181. *
  182. * @param string $text
  183. * @retval object QueryPath
  184. */
  185. public function appendElement($text) {
  186. if (isset ($text)) {
  187. foreach ($this->qp->get() as $element) {
  188. $node = $this->qp->createElement($text);
  189. qp($element)->append($node);
  190. }
  191. }
  192. return $this->qp;
  193. }
  194. }
  195. QueryPathExtensionRegistry::extend('QPXML');