210 lines
5.8 KiB
PHP
210 lines
5.8 KiB
PHP
<?php
|
|
/** @file
|
|
* XML extensions. See QPXML.
|
|
*/
|
|
/**
|
|
* Provide QueryPath with additional XML tools.
|
|
*
|
|
* @author M Butcher <matt@aleph-null.tv>
|
|
* @author Xander Guzman <theshadow@shadowpedia.info>
|
|
* @license http://opensource.org/licenses/lgpl-2.1.php LGPL or MIT-like license.
|
|
* @see QueryPathExtension
|
|
* @see QueryPathExtensionRegistry::extend()
|
|
* @see QPXML
|
|
* @ingroup querypath_extensions
|
|
*/
|
|
class QPXML implements QueryPathExtension {
|
|
|
|
protected $qp;
|
|
|
|
public function __construct(QueryPath $qp) {
|
|
$this->qp = $qp;
|
|
}
|
|
|
|
public function schema($file) {
|
|
$doc = $this->qp->branch()->top()->get(0)->ownerDocument;
|
|
|
|
if (!$doc->schemaValidate($file)) {
|
|
throw new QueryPathException('Document did not validate against the schema.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get or set a CDATA section.
|
|
*
|
|
* If this is given text, it will create a CDATA section in each matched element,
|
|
* setting that item's value to $text.
|
|
*
|
|
* If no parameter is passed in, this will return the first CDATA section that it
|
|
* finds in the matched elements.
|
|
*
|
|
* @param string $text
|
|
* The text data to insert into the current matches. If this is NULL, then the first
|
|
* CDATA will be returned.
|
|
*
|
|
* @return mixed
|
|
* If $text is not NULL, this will return a {@link QueryPath}. Otherwise, it will
|
|
* return a string. If no CDATA is found, this will return NULL.
|
|
* @see comment()
|
|
* @see QueryPath::text()
|
|
* @see QueryPath::html()
|
|
*/
|
|
public function cdata($text = NULL) {
|
|
if (isset($text)) {
|
|
// Add this text as CDATA in the current elements.
|
|
foreach ($this->qp->get() as $element) {
|
|
$cdata = $element->ownerDocument->createCDATASection($text);
|
|
$element->appendChild($cdata);
|
|
}
|
|
return $this->qp;;
|
|
}
|
|
|
|
// Look for CDATA sections.
|
|
foreach ($this->qp->get() as $ele) {
|
|
foreach ($ele->childNodes as $node) {
|
|
if ($node->nodeType == XML_CDATA_SECTION_NODE) {
|
|
// Return first match.
|
|
return $node->textContent;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
// Nothing found
|
|
}
|
|
|
|
/**
|
|
* Get or set a comment.
|
|
*
|
|
* This function is used to get or set comments in an XML or HTML document.
|
|
* If a $text value is passed in (and is not NULL), then this will add a comment
|
|
* (with the value $text) to every match in the set.
|
|
*
|
|
* If no text is passed in, this will return the first comment in the set of matches.
|
|
* If no comments are found, NULL will be returned.
|
|
*
|
|
* @param string $text
|
|
* The text of the comment. If set, a new comment will be created in every item
|
|
* wrapped by the current {@link QueryPath}.
|
|
* @return mixed
|
|
* If $text is set, this will return a {@link QueryPath}. If no text is set, this
|
|
* will search for a comment and attempt to return the string value of the first
|
|
* comment it finds. If no comment is found, NULL will be returned.
|
|
* @see cdata()
|
|
*/
|
|
public function comment($text = NULL) {
|
|
if (isset($text)) {
|
|
foreach ($this->qp->get() as $element) {
|
|
$comment = $element->ownerDocument->createComment($text);
|
|
$element->appendChild($comment);
|
|
}
|
|
return $this->qp;
|
|
}
|
|
foreach ($this->qp->get() as $ele) {
|
|
foreach ($ele->childNodes as $node) {
|
|
if ($node->nodeType == XML_COMMENT_NODE) {
|
|
// Return first match.
|
|
return $node->textContent;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get or set a processor instruction.
|
|
*/
|
|
public function pi($prefix = NULL, $text = NULL) {
|
|
if (isset($text)) {
|
|
foreach ($this->qp->get() as $element) {
|
|
$comment = $element->ownerDocument->createProcessingInstruction($prefix, $text);
|
|
$element->appendChild($comment);
|
|
}
|
|
return $this->qp;
|
|
}
|
|
foreach ($this->qp->get() as $ele) {
|
|
foreach ($ele->childNodes as $node) {
|
|
if ($node->nodeType == XML_PI_NODE) {
|
|
|
|
if (isset($prefix)) {
|
|
if ($node->tagName == $prefix) {
|
|
return $node->textContent;
|
|
}
|
|
}
|
|
else {
|
|
// Return first match.
|
|
return $node->textContent;
|
|
}
|
|
}
|
|
} // foreach
|
|
} // foreach
|
|
}
|
|
public function toXml() {
|
|
return $this->qp->document()->saveXml();
|
|
}
|
|
|
|
/**
|
|
* Create a NIL element.
|
|
*
|
|
* @param string $text
|
|
* @param string $value
|
|
* @reval object $element
|
|
*/
|
|
public function createNilElement($text, $value) {
|
|
$value = ($value)? 'true':'false';
|
|
$element = $this->qp->createElement($text);
|
|
$element->attr('xsi:nil', $value);
|
|
return $element;
|
|
}
|
|
|
|
/**
|
|
* Create an element with the given namespace.
|
|
*
|
|
* @param string $text
|
|
* @param string $nsUri
|
|
* The namespace URI for the given element.
|
|
* @retval object
|
|
*/
|
|
public function createElement($text, $nsUri = null) {
|
|
if (isset ($text)) {
|
|
foreach ($this->qp->get() as $element) {
|
|
if ($nsUri === null && strpos($text, ':') !== false) {
|
|
$ns = array_shift(explode(':', $text));
|
|
$nsUri = $element->ownerDocument->lookupNamespaceURI($ns);
|
|
|
|
if ($nsUri === null) {
|
|
throw new QueryPathException("Undefined namespace for: " . $text);
|
|
}
|
|
}
|
|
|
|
$node = null;
|
|
if ($nsUri !== null) {
|
|
$node = $element->ownerDocument->createElementNS(
|
|
$nsUri,
|
|
$text
|
|
);
|
|
} else {
|
|
$node = $element->ownerDocument->createElement($text);
|
|
}
|
|
return qp($node);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Append an element.
|
|
*
|
|
* @param string $text
|
|
* @retval object QueryPath
|
|
*/
|
|
public function appendElement($text) {
|
|
if (isset ($text)) {
|
|
foreach ($this->qp->get() as $element) {
|
|
$node = $this->qp->createElement($text);
|
|
qp($element)->append($node);
|
|
}
|
|
}
|
|
return $this->qp;
|
|
}
|
|
}
|
|
QueryPathExtensionRegistry::extend('QPXML');
|