Subversion Repositories PHPX

Compare Revisions

Last modification

Ignore whitespace Rev 41 → Rev 42

/trunk/dom/tests/DOMDocument2Test.php
New file
0,0 → 1,48
<?php
 
require_once __DIR__ . '/../DOMDocument2.php';
 
use de\pointedears\dom\DOMDocument2;
 
class DOMDocument2Test extends \PHPUnit_Framework_Testcase
{
public function testRenameElementNode ()
{
$d = new DOMDocument2();
$d->appendChild($d->createElement("foo"))
->appendChild($d->createElement("bar"))
->setAttributeNS(null, 'evil', 23);
$d->firstChild->setAttributeNS(null, 'answer', 42);
 
echo "\nBefore:\n\n" . $d->saveXML() . "\n";
 
$d->renameNode($d->firstChild, null, "baz");
echo "After:\n\n" . $d->saveXML() . "\n";
 
$this->assertTrue($d->firstChild->nodeName === 'baz');
$this->assertTrue($d->firstChild->firstChild->nodeName === 'bar');
}
 
public function testRenameAttributeNode ()
{
$d = new DOMDocument2();
$d->appendChild($d->createElement("foo"))
->setAttributeNS(null, 'evil', 42);
 
echo "\nBefore:\n\n" . $d->saveXML() . "\n";
 
$attrNode = $d->firstChild->getAttributeNode("evil");
 
$d->renameNode($attrNode, null, "answer");
echo "After:\n\n" . $d->saveXML();
 
$this->assertTrue($d->firstChild->getAttribute("answer") === "42");
}
 
public function testRenameStandaloneAttr ()
{
$d = new DOMDocument2();
$attr = $d->renameNode(new \DOMAttr('evil', '42'), null, "answer");
$this->assertTrue($attr->name === "answer" && $attr->value === "42");
}
}
/trunk/dom/DOMDocument2.php
New file
0,0 → 1,93
<?php
 
namespace de\pointedears\dom;
 
class DOMDocument2 extends \DOMDocument
{
/**
* Renames an existing node of type <code>XML_ELEMENT_NODE</code>
* or <code>XML_ATTRIBUTE_NODE</code>
*
* @param \DOMNode $node
* @param string $namespaceURI = null
* @param string $qualifiedName
* @return \DOMNode The renamed node
*/
public function renameNode (\DOMNode $node, $namespaceURI,
$qualifiedName)
{
$result = false;
 
if ($node->nodeType === XML_ELEMENT_NODE)
{
/*
* Per W3C DOM Level 3 Core
* <http://www.w3.org/TR/DOM-Level-3-Core/core.html#Document3-renameNode>
*
* "If simply changing the name of the given node is not possible,
* the following operations are performed:
*
* a new node is created, ...
*/
$newNode = $this->createElementNS($namespaceURI,
$qualifiedName, $node->nodeValue);
 
/*
* any registered event listener is registered on the new node
* [skipped], any user data attached to the old node is removed
* from that node the old node is removed from its parent if it
* has one [done by replaceChild]
*/
 
/* the children are moved to the new node */
while (($childNode = $node->firstChild))
{
$newNode->appendChild($childNode);
}
 
/*
* if the renamed node is an Element its attributes are moved
* to the new node,
*/
foreach ($node->attributes as $attribute)
{
$newNode->setAttributeNodeNS($attribute);
}
/*
* the new node is inserted at the position the old node used
* to have in its parent's child nodes list if it has one,
* the user data that was attached to the old node is attached
* to the new node."
*/
$result = $node->parentNode->replaceChild($newNode, $node);
}
else if ($node->nodeType === XML_ATTRIBUTE_NODE)
{
/*
* "When the node being renamed is an Attr that is attached
* to an Element, the node is first removed from the Element
* attributes map. Then, once renamed, either by modifying
* the existing node or creating a new one as described above,
* it is put back."
*/
if (($ownerElement = $node->ownerElement))
{
$ownerElement->removeAttributeNS($node->namespaceURI, $node->name);
 
$result = $ownerElement->setAttributeNS($namespaceURI, $qualifiedName, $node->value);
 
if ($result !== false)
{
$newNode = $ownerElement->getAttributeNode($qualifiedName);
}
}
else
{
/* Standalone attribute node */
return new \DOMAttr($qualifiedName, $node->value);
}
}
 
return ($result === false ? false : $newNode);
}
}