1. <?php
  2. /**
  3. * Deduplicates DOM elements within a given DOM node.
  4. *
  5. * @param DOMNode $node The DOM node to process.
  6. * @param bool $strict Whether to perform a strict comparison (===). Defaults to true.
  7. * @param bool $recursive Whether to process child nodes recursively. Defaults to true.
  8. * @return DOMNode The modified DOM node.
  9. */
  10. function deduplicateDOMElements(DOMNode $node, bool $strict = true, bool $recursive = true): DOMNode
  11. {
  12. if (!$node instanceof DOMNode) {
  13. return $node; // or throw an exception
  14. }
  15. if ($recursive) {
  16. foreach ($node->childNodes as $child) {
  17. $node = deduplicateDOMElements($child, $strict, $recursive);
  18. }
  19. }
  20. $elements = [];
  21. $newChildren = [];
  22. foreach ($node->childNodes as $child) {
  23. if ($child instanceof Element) {
  24. $isDuplicate = false;
  25. foreach ($elements as $element) {
  26. if ($strict) {
  27. if ($element === $child) {
  28. $isDuplicate = true;
  29. break;
  30. }
  31. } else {
  32. //Loose comparison
  33. if ($element == $child) {
  34. $isDuplicate = true;
  35. break;
  36. }
  37. }
  38. }
  39. if (!$isDuplicate) {
  40. $elements[] = $child;
  41. $newChildren[] = $child;
  42. }
  43. } else {
  44. $newChildren[] = $child; // Keep non-element nodes
  45. }
  46. }
  47. $node->appendChild($Document->createElement('fragment')); // Create a fragment to hold the new children
  48. $fragment = $node->firstChild;
  49. foreach ($newChildren as $child) {
  50. $fragment->appendChild($child);
  51. }
  52. return $node;
  53. }
  54. //Example Usage
  55. /*
  56. $Document = new DOMDocument();
  57. $element = $Document->createElement('div');
  58. $element->appendChild($Document->createElement('p'));
  59. $element->appendChild($Document->createElement('p'));
  60. $element->appendChild($Document->createElement('span'));
  61. $element->appendChild($Document->createElement('span'));
  62. $node = $Document->appendChild($element);
  63. $deduplicatedNode = deduplicateDOMElements($node);
  64. echo $deduplicatedNode->outerHTML;
  65. */
  66. ?>

Add your comment