Ok, so I had this neat little idea the other night to create a helper class for DOMDOCUMENT that mimics, to some extent, jQuery's ability to manipulate the DOM of an HTML or XML-based string. Instead of css selectors, XPath is used. For example:
$Xml->load($source)
->path('//root/items')
->each(function($Context)
{
echo $Context->nodeValue;
});
This would invoke a callback function on every resulting node. Unfortunately, PHP version < 5.3.x doesn't support lambda functions or closures, so I'm forced to do something a bit more like this for the time being:
$Xml->load($source)
->path('//root/items')
->walk('printValue', 'param1', 'param2');
Everything is working great at the moment and I think this project would be useful to a lot of people, but I'm stuck with one of the functions. I am attempting to mimic jQuery's 'replace' method. Using the following code, I can accomplish this quite easily by applying the following method:
$Xml->load($source)
->path('//root/items')
->replace($Xml->createElement('foo', 'bar')); // can be an object, string or XPath pattern
The code behind this method is:
public function replace($Content)
{
foreach($this->results as $Element)
{
$Element->parentNode->appendChild($Content->cloneNode(true));
$Element->parentNode->removeChild($Element);
}
return $this;
}
Now, this works. It replaces every resulting element with a cloned version of $Content. The problem is that it adds them to the bottom of the parent node's list of children. The question is, how do I clone this element to replace other elements, while still retaining the original position in the DOM?
I was thinking about reverse-engineering the node I was to replace. Basically, copying over values, attributes and element name from $Content, but I am unable to change the actual element name of the target element.
Reflection could be a possibility, but there's gotta be an easier way to do this.
Anybody?