Subversion Repositories PHPX

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
42 PointedEar 1
<?php
2
 
3
namespace de\pointedears\dom;
4
 
5
class DOMDocument2 extends \DOMDocument
6
{
7
  /**
8
   * Renames an existing node of type <code>XML_ELEMENT_NODE</code>
9
   * or <code>XML_ATTRIBUTE_NODE</code>
10
   *
11
   * @param \DOMNode $node
12
   * @param string $namespaceURI = null
13
   * @param string $qualifiedName
14
   * @return \DOMNode The renamed node
15
   */
16
  public function renameNode (\DOMNode $node, $namespaceURI,
17
    $qualifiedName)
18
  {
19
    $result = false;
20
 
21
    if ($node->nodeType === XML_ELEMENT_NODE)
22
    {
23
      /*
24
       * Per W3C DOM Level 3 Core
25
       * <http://www.w3.org/TR/DOM-Level-3-Core/core.html#Document3-renameNode>
26
       *
27
       * "If simply changing the name of the given node is not possible,
28
       * the following operations are performed:
29
       *
30
       * a new node is created, ...
31
       */
32
      $newNode = $this->createElementNS($namespaceURI,
33
        $qualifiedName, $node->nodeValue);
34
 
35
      /*
36
       * any registered event listener is registered on the new node
37
       * [skipped], any user data attached to the old node is removed
38
       * from that node the old node is removed from its parent if it
39
       * has one [done by replaceChild]
40
       */
41
 
42
      /* the children are moved to the new node */
43
      while (($childNode = $node->firstChild))
44
      {
45
        $newNode->appendChild($childNode);
46
      }
47
 
48
      /*
49
       * if the renamed node is an Element its attributes are moved
50
       * to the new node,
51
       */
52
      foreach ($node->attributes as $attribute)
53
      {
54
        $newNode->setAttributeNodeNS($attribute);
55
      }
56
      /*
57
       * the new node is inserted at the position the old node used
58
       * to have in its parent's child nodes list if it has one,
59
       * the user data that was attached to the old node is attached
60
       * to the new node."
61
       */
62
      $result = $node->parentNode->replaceChild($newNode, $node);
63
    }
64
    else if ($node->nodeType === XML_ATTRIBUTE_NODE)
65
    {
66
      /*
67
       * "When the node being renamed is an Attr that is attached
68
       * to an Element, the node is first removed from the Element
69
       * attributes map. Then, once renamed, either by modifying
70
       * the existing node or creating a new one as described above,
71
       * it is put back."
72
       */
73
      if (($ownerElement = $node->ownerElement))
74
      {
75
        $ownerElement->removeAttributeNS($node->namespaceURI, $node->name);
76
 
77
        $result = $ownerElement->setAttributeNS($namespaceURI, $qualifiedName, $node->value);
78
 
79
        if ($result !== false)
80
        {
81
          $newNode = $ownerElement->getAttributeNode($qualifiedName);
82
        }
83
      }
84
      else
85
      {
86
        /* Standalone attribute node */
87
        return new \DOMAttr($qualifiedName, $node->value);
88
      }
89
    }
90
 
91
    return ($result === false ? false : $newNode);
92
  }
93
}