Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

@ added documentElement

- avoided using the buggy set_content for the Data functions, using replace_child and create_text_node instead
- parent::node() now for relative xpath queries
@ ability to make xpath sort permanent in the tree (limited to siblings queries only)


git-svn-id: http://svn.php.net/repository/pear/packages/XML_XPath/trunk@91820 c90b9560-bf6c-de11-be94-00142212c4b1
  • Loading branch information...
commit 94f328701ca2f9c6ebf3d642393d73e2f95b85c1 1 parent 302355b
Daniel Allen authored
Showing with 72 additions and 17 deletions.
  1. +13 −11 TODO
  2. +39 −4 XPath/common.php
  3. +20 −2 XPath/result.php
View
24 TODO
@@ -22,11 +22,6 @@ XML_XPath Inteface TODO:
[@] implement childNodes() to return an xml_xpath_result object, Fix sorting in result
object for DOM queries
- [*] make a short test harness just so I know I don't commit bad shit
-
- [*] finally figured out substitute entities default, so see if we can make this
- usable in the class
-
[@] implement getElementsByTagName since there are domxml functions
now...return as getElementsByTagName as XML_XPath_result objects
@@ -35,6 +30,7 @@ XML_XPath Inteface TODO:
[@] functions for result object are now
next()
rewind()
+ current()
end()
nextByNodeName()
nextByNodeType()
@@ -47,17 +43,23 @@ XML_XPath Inteface TODO:
[@] relative xpath queries in evaluate
- [*] fix this stdClass hack we have to do to get the result object to work with non xpath
+ [@] fix this stdClass hack we have to do to get the result object to work with non xpath
queries (in cases of using dom queries)
- [*] waiting on stripping of formatting on the way in
-
- [*] insert_before() now copies node before inserting, does this affect us?
-
- [@] when using getAttribute with the move = true, we should sit on the attribute node, not the parent element
+ [@] when using getAttribute with the move = true, we should sit on the attribute node,
+ not the parent element
[@] manually do the xpath_eval in the quick xpath query function, much faster
[@] elimiate _quick_evaluate_shutdown? to slow in critical areas
+ [*] waiting on stripping of formatting on the way in
+
+ [*] insert_before() now copies node before inserting, does this affect us?
+
[*] figure out a way to implement the create functions
+
+ [*] make a short test harness just so I know I don't commit bad shit
+
+ [*] finally figured out substitute entities default, so see if we can make this
+ usable in the class
View
43 XPath/common.php
@@ -240,6 +240,33 @@ function getElementsByTagName($in_tagName)
}
// }}}
+ // {{{ boolean documentElement()
+
+ /**
+ * Move to the document element
+ *
+ * @param boolean $in_movePointer (optional) move the internal pointer or return reference
+ *
+ * @access public
+ * @return boolean whether pointer was moved or object pointer to document element
+ */
+ function documentElement($in_movePointer = true)
+ {
+ if (!$this->pointer) {
+ return PEAR::raiseError(null, XML_XPATH_NULL_POINTER, null, E_USER_WARNING, '', 'XML_XPath_Error', true);
+ }
+
+ $documentElement = $this->xml->document_element();
+ if ($in_movePointer) {
+ $this->pointer = $documentElement;
+ return true;
+ }
+ else {
+ return $documentElement;
+ }
+ }
+
+ // }}}
// {{{ boolean parentNode()
/**
@@ -1385,7 +1412,7 @@ function &evaluate($in_xpathQuery, $in_movePointer = false)
if ($in_xpathQuery[0] == 'current()' || $in_xpathQuery[0] == '.') {
$in_xpathQuery[0] = $this->getNodePath($this->pointer);
}
- elseif ($in_xpathQuery[0] == 'parent()' || $in_xpathQuery[0] == '..') {
+ elseif ($in_xpathQuery[0] == 'parent::node()' || $in_xpathQuery[0] == '..') {
if ($this->pointer->node_type() != XML_DOCUMENT_NODE) {
$in_xpathQuery[0] = $this->getNodePath($this->pointer->parent_node());
}
@@ -1471,7 +1498,7 @@ function _set_content($in_content, $in_xpathQuery, $in_movePointer, $in_replace,
return PEAR::raiseError(null, XML_XPATH_NULL_POINTER, null, E_USER_WARNING, '', 'XML_XPath_Error', true);
}
- if (XML_XPath::isError($result = $this->_quick_evaluate_init($in_xpathQuery, $in_movePointer, array(XML_TEXT_NODE, XML_CDATA_SECTION_NODE, XML_COMMENT_NODE, XML_PI_NODE)))) {
+ if (XML_XPath::isError($result = $this->_quick_evaluate_init($in_xpathQuery, $in_movePointer, array(XML_ELEMENT_NODE, XML_TEXT_NODE, XML_CDATA_SECTION_NODE, XML_COMMENT_NODE, XML_PI_NODE)))) {
return $result;
}
@@ -1491,7 +1518,15 @@ function _set_content($in_content, $in_xpathQuery, $in_movePointer, $in_replace,
else {
$data = substr($data, 0, $in_offset) . $in_content . substr($data, $in_offset);
}
- $this->pointer->set_content($data);
+
+ if ($this->pointer->node_type() == XML_ELEMENT_NODE) {
+ $this->replaceChildren($data);
+ }
+ else {
+ $this->pointer->replace_node($this->xml->create_text_node($data));
+ }
+
+ $return = null;
}
if (!is_null($in_xpathQuery) && !$in_movePointer) {
@@ -1571,7 +1606,7 @@ function _quick_evaluate_init($in_xpathQuery = null, $in_movePointer = false, $i
if ($in_xpathQuery[0] == 'current()' || $in_xpathQuery[0] == '.') {
$in_xpathQuery[0] = $this->getNodePath($this->pointer);
}
- elseif ($in_xpathQuery[0] == 'parent()' || $in_xpathQuery[0] == '..') {
+ elseif ($in_xpathQuery[0] == 'parent::node()' || $in_xpathQuery[0] == '..') {
if ($this->pointer->node_type() != XML_DOCUMENT_NODE) {
$in_xpathQuery[0] = $this->getNodePath($this->pointer->parent_node());
}
View
22 XPath/result.php
@@ -199,7 +199,7 @@ function getIndex()
* @access public
* @return boolean success {or XML_XPath_Error exception}
*/
- function sort($in_sortXpath = '.', $in_order = XML_XPATH_SORT_TEXT_ASCENDING)
+ function sort($in_sortXpath = '.', $in_order = XML_XPATH_SORT_TEXT_ASCENDING, $in_permanent = false)
{
// make sure we are dealing with a result that is a nodeset
if ($this->type != XPATH_NODESET) {
@@ -227,7 +227,7 @@ function sort($in_sortXpath = '.', $in_order = XML_XPATH_SORT_TEXT_ASCENDING)
// in sorted order and then just weed out the nodes I used to sort.
$xpathResult = @$this->ctx->xpath_eval($this->query . '/' . $in_sortXpath . '|' . $this->query);
if (!$xpathResult || empty($xpathResult->nodeset)) {
- return PEAR::raiseError(null, XML_XPATH_INVALID_QUERY, null, E_USER_NOTICE, "Query {$this->query}/$in_sortXPath", 'XML_XPath_Error', true);
+ return PEAR::raiseError(null, XML_XPATH_INVALID_QUERY, null, E_USER_NOTICE, "Query {$this->query}/$in_sortXpath", 'XML_XPath_Error', true);
}
// Sorting Process:
@@ -306,6 +306,24 @@ function sort($in_sortXpath = '.', $in_order = XML_XPATH_SORT_TEXT_ASCENDING)
}
$this->data = $dataReordered;
+
+ // if this is a permanent sort, make the change to the main tree
+ if ($in_permanent && $parent = $this->data[0]->parent_node()) {
+ // nix all the children by overwriting node and fixing attributes
+ $attributes = $parent->has_attributes() ? $parent->attributes() : array();
+ $parent->replace_node($clone = $parent->clone_node());
+ $parent = $clone;
+
+ foreach($attributes as $attributeNode) {
+ // waiting on set_attribute_node() to work here
+ $parent->set_attribute($attributeNode->node_name(), $attributeNode->value());
+ }
+
+ foreach ($this->data as $sortedNode) {
+ $parent->append_child($sortedNode);
+ }
+ }
+
// rewind to the beginning of the data set
$this->rewind();
Please sign in to comment.
Something went wrong with that request. Please try again.