diff --git a/README.md b/README.md
index 37a7010..46404fa 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
## Overview
-s9e\\SweetDOM is a library that extends [PHP's DOM extension](https://www.php.net/manual/en/book.dom.php) with a set of methods designed to simplify and facilitate the manipulation of XSLT 1.0 templates.
+s9e\\SweetDOM is a library that extends [PHP's DOM extension](https://www.php.net/manual/en/book.dom.php) to make DOM manipulation easier, with a particular emphasis on XSLT 1.0 templates. It adds syntactic sugar for the most common DOM operations, [improves compatibility](#backward-and-forward-compatibility-with-older-and-future-versions-of-php) across PHP versions, and implements polyfills for some of the newer methods.
[![Code Coverage](https://scrutinizer-ci.com/g/s9e/SweetDOM/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/s9e/SweetDOM/?branch=master)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/s9e/SweetDOM/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/s9e/SweetDOM/?branch=master)
@@ -173,6 +173,7 @@ In order to improve compatibility with older versions of PHP as well as future v
Polyfills for the following methods are provided for PHP < 8.3:
+ - `Node::isEqualNode`
- `ParentNode::insertAdjacentElement`
- `ParentNode::insertAdjacentText`
- `ParentNode::replaceChildren`
diff --git a/src/Document.php b/src/Document.php
index 6876ebe..711f645 100644
--- a/src/Document.php
+++ b/src/Document.php
@@ -13,7 +13,7 @@
use DOMXPath;
use RuntimeException;
use const PHP_VERSION;
-use function func_get_args, libxml_get_last_error, trim, version_compare;
+use function func_get_args, method_exists, libxml_get_last_error, trim, version_compare;
/**
* @method Attr|false createAttribute(string $localName)
@@ -66,6 +66,13 @@ public function firstOf(string $expression, ?DOMNode $contextNode = null, bool $
return $this->query(...func_get_args())->item(0);
}
+ public function isEqualNode(?DOMNode $otherNode): bool
+ {
+ return method_exists('DOMDocument', 'isEqualNode')
+ ? parent::isEqualNode($otherNode)
+ : NodeComparator::isEqualNode($this, $otherNode);
+ }
+
/**
* Evaluate and return the result of a given XPath query
*/
diff --git a/src/ForwardCompatibleNodes/Attr.php b/src/ForwardCompatibleNodes/Attr.php
index 1141bdd..50e05fb 100644
--- a/src/ForwardCompatibleNodes/Attr.php
+++ b/src/ForwardCompatibleNodes/Attr.php
@@ -8,7 +8,9 @@
namespace s9e\SweetDOM\ForwardCompatibleNodes;
use s9e\SweetDOM\Attr as ParentClass;
+use s9e\SweetDOM\NodeTraits\NodePolyfill;
class Attr extends ParentClass
{
+ use NodePolyfill;
}
\ No newline at end of file
diff --git a/src/ForwardCompatibleNodes/CdataSection.php b/src/ForwardCompatibleNodes/CdataSection.php
index 10763e4..222570d 100644
--- a/src/ForwardCompatibleNodes/CdataSection.php
+++ b/src/ForwardCompatibleNodes/CdataSection.php
@@ -9,8 +9,10 @@
use s9e\SweetDOM\CdataSection as ParentClass;
use s9e\SweetDOM\NodeTraits\ChildNodeForwardCompatibility;
+use s9e\SweetDOM\NodeTraits\NodePolyfill;
class CdataSection extends ParentClass
{
use ChildNodeForwardCompatibility;
+ use NodePolyfill;
}
\ No newline at end of file
diff --git a/src/ForwardCompatibleNodes/Comment.php b/src/ForwardCompatibleNodes/Comment.php
index 143448c..dcb889a 100644
--- a/src/ForwardCompatibleNodes/Comment.php
+++ b/src/ForwardCompatibleNodes/Comment.php
@@ -9,8 +9,10 @@
use s9e\SweetDOM\Comment as ParentClass;
use s9e\SweetDOM\NodeTraits\ChildNodeForwardCompatibility;
+use s9e\SweetDOM\NodeTraits\NodePolyfill;
class Comment extends ParentClass
{
use ChildNodeForwardCompatibility;
+ use NodePolyfill;
}
\ No newline at end of file
diff --git a/src/ForwardCompatibleNodes/DocumentFragment.php b/src/ForwardCompatibleNodes/DocumentFragment.php
index 67b1963..db93738 100644
--- a/src/ForwardCompatibleNodes/DocumentFragment.php
+++ b/src/ForwardCompatibleNodes/DocumentFragment.php
@@ -8,9 +8,11 @@
namespace s9e\SweetDOM\ForwardCompatibleNodes;
use s9e\SweetDOM\DocumentFragment as ParentClass;
+use s9e\SweetDOM\NodeTraits\NodePolyfill;
use s9e\SweetDOM\NodeTraits\ParentNodePolyfill;
class DocumentFragment extends ParentClass
{
+ use NodePolyfill;
use ParentNodePolyfill;
}
\ No newline at end of file
diff --git a/src/ForwardCompatibleNodes/Element.php b/src/ForwardCompatibleNodes/Element.php
index 876622e..16604ba 100644
--- a/src/ForwardCompatibleNodes/Element.php
+++ b/src/ForwardCompatibleNodes/Element.php
@@ -9,10 +9,12 @@
use s9e\SweetDOM\Element as ParentClass;
use s9e\SweetDOM\NodeTraits\ChildNodeForwardCompatibility;
+use s9e\SweetDOM\NodeTraits\NodePolyfill;
use s9e\SweetDOM\NodeTraits\ParentNodePolyfill;
class Element extends ParentClass
{
use ChildNodeForwardCompatibility;
+ use NodePolyfill;
use ParentNodePolyfill;
}
\ No newline at end of file
diff --git a/src/ForwardCompatibleNodes/Text.php b/src/ForwardCompatibleNodes/Text.php
index 54f32d1..c03a743 100644
--- a/src/ForwardCompatibleNodes/Text.php
+++ b/src/ForwardCompatibleNodes/Text.php
@@ -8,9 +8,11 @@
namespace s9e\SweetDOM\ForwardCompatibleNodes;
use s9e\SweetDOM\NodeTraits\ChildNodeForwardCompatibility;
+use s9e\SweetDOM\NodeTraits\NodePolyfill;
use s9e\SweetDOM\Text as ParentClass;
class Text extends ParentClass
{
use ChildNodeForwardCompatibility;
+ use NodePolyfill;
}
\ No newline at end of file
diff --git a/src/NodeComparator.php b/src/NodeComparator.php
new file mode 100644
index 0000000..053fa3c
--- /dev/null
+++ b/src/NodeComparator.php
@@ -0,0 +1,177 @@
+nodeType !== $otherNode->nodeType)
+ {
+ return false;
+ }
+ $classes = [
+ 'DOMElement',
+ 'DOMCharacterData',
+ 'DOMProcessingInstruction',
+ 'DOMAttr',
+ 'DOMDocument',
+ 'DOMDocumentFragment',
+ 'DOMDocumentType',
+ 'DOMEntityReference',
+ 'DOMEntity',
+ 'DOMNotation'
+ ];
+ foreach ($classes as $className)
+ {
+ if ($node instanceof $className && $otherNode instanceof $className)
+ {
+ $methodName = 'isEqual' . substr($className, 3);
+
+ return static::$methodName($node, $otherNode);
+ }
+ }
+
+ // @codeCoverageIgnoreStart
+ return $node->isSameNode($otherNode);
+ // @codeCoverageIgnoreEnd
+ }
+
+ /**
+ * @return array
+ */
+ protected static function getNamespaceDeclarations(DOMElement $element): array
+ {
+ $namespaces = [];
+ $xpath = new DOMXPath($element->ownerDocument);
+ foreach ($xpath->query('namespace::*', $element) as $node)
+ {
+ if ($element->hasAttribute($node->nodeName))
+ {
+ $namespaces[$node->nodeName] = $node->nodeValue;
+ }
+ }
+
+ return $namespaces;
+ }
+
+ protected static function hasEqualNamespaceDeclarations(DOMElement $element, DOMElement $otherElement): bool
+ {
+ return static::getNamespaceDeclarations($element) == static::getNamespaceDeclarations($otherElement);
+ }
+
+ protected static function isEqualAttr(DOMAttr $node, DOMAttr $otherNode): bool
+ {
+ return $node->namespaceURI === $otherNode->namespaceURI
+ && $node->localName === $otherNode->localName
+ && $node->value === $otherNode->value;
+ }
+
+ protected static function isEqualCharacterData(DOMCharacterData $node, DOMCharacterData $otherNode): bool
+ {
+ // Covers DOMCdataSection, DOMComment, and DOMText
+ return $node->data === $otherNode->data;
+ }
+
+ protected static function isEqualDocument(DOMDocument $node, DOMDocument $otherNode): bool
+ {
+ return static::isEqualNodeList($node->childNodes, $otherNode->childNodes);
+ }
+
+ protected static function isEqualDocumentFragment(DOMDocumentFragment $node, DOMDocumentFragment $otherNode): bool
+ {
+ return static::isEqualNodeList($node->childNodes, $otherNode->childNodes);
+ }
+
+ protected static function isEqualDocumentType(DOMDocumentType $node, DOMDocumentType $otherNode): bool
+ {
+ return $node->name === $otherNode->name
+ && $node->publicId === $otherNode->publicId
+ && $node->systemId === $otherNode->systemId;
+ }
+
+ protected static function isEqualElement(DOMElement $element, DOMElement $otherElement): bool
+ {
+ if ($element->namespaceURI !== $otherElement->namespaceURI
+ || $element->nodeName !== $otherElement->nodeName
+ || $element->attributes->length !== $otherElement->attributes->length
+ || $element->childNodes->length !== $otherElement->childNodes->length)
+ {
+ return false;
+ }
+
+ foreach ($element->attributes as $attribute)
+ {
+ if ($attribute->value !== $otherElement->attributes->getNamedItem($attribute->name)?->value)
+ {
+ return false;
+ }
+ }
+
+ return static::isEqualNodeList($element->childNodes, $otherElement->childNodes)
+ && static::hasEqualNamespaceDeclarations($element, $otherElement);
+ }
+
+ protected static function isEqualEntity(DOMEntity $node, DOMEntity $otherNode): bool
+ {
+ return $node->nodeName === $otherNode->nodeName
+ && $node->publicId === $otherNode->publicId
+ && $node->systemId === $otherNode->systemId;
+ }
+
+ protected static function isEqualEntityReference(DOMEntityReference $node, DOMEntityReference $otherNode): bool
+ {
+ return $node->nodeName === $otherNode->nodeName;
+ }
+
+ protected static function isEqualNodeList(DOMNodeList $list, DOMNodeList $otherList): bool
+ {
+ if ($list->length !== $otherList->length)
+ {
+ return false;
+ }
+ foreach ($list as $i => $node)
+ {
+ if (!static::isEqualNode($node, $otherList->item($i)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected static function isEqualNotation(DOMNotation $node, DOMNotation $otherNode): bool
+ {
+ return $node->nodeName === $otherNode->nodeName
+ && $node->publicId === $otherNode->publicId
+ && $node->systemId === $otherNode->systemId;
+ }
+
+ protected static function isEqualProcessingInstruction(DOMProcessingInstruction $node, DOMProcessingInstruction $otherNode): bool
+ {
+ return $node->target === $otherNode->target && $node->data === $otherNode->data;
+ }
+}
\ No newline at end of file
diff --git a/src/NodeTraits/NodePolyfill.php b/src/NodeTraits/NodePolyfill.php
new file mode 100644
index 0000000..fea5ed4
--- /dev/null
+++ b/src/NodeTraits/NodePolyfill.php
@@ -0,0 +1,22 @@
+loadXML('');
+
+ $this->assertFalse($dom->firstOf('//y/@a')->isEqualNode($dom->firstOf('//z/@a')));
+ $this->assertFalse($dom->firstOf('//y/@a')->isEqualNode($dom->firstOf('//z/@b')));
+ $this->assertFalse($dom->firstOf('//y/@a')->isEqualNode($dom->firstOf('//z/@c')));
+ $this->assertFalse($dom->firstOf('//y/@b')->isEqualNode($dom->firstOf('//z/@a')));
+ $this->assertTrue($dom->firstOf('//y/@b')->isEqualNode($dom->firstOf('//z/@b')));
+ $this->assertFalse($dom->firstOf('//y/@b')->isEqualNode($dom->firstOf('//z/@c')));
+ $this->assertFalse($dom->firstOf('//y/@c')->isEqualNode($dom->firstOf('//z/@a')));
+ $this->assertFalse($dom->firstOf('//y/@c')->isEqualNode($dom->firstOf('//z/@b')));
+ $this->assertFalse($dom->firstOf('//y/@c')->isEqualNode($dom->firstOf('//z/@c')));
+ }
+}
\ No newline at end of file
diff --git a/tests/CdataSectionTest.php b/tests/CdataSectionTest.php
index 7badf87..ff094f5 100644
--- a/tests/CdataSectionTest.php
+++ b/tests/CdataSectionTest.php
@@ -81,4 +81,13 @@ public function testQuery()
$this->assertEquals('z', $dom->firstOf('//text()')->query('.//following-sibling::x')->item(0)->getAttribute('id'));
}
+
+ public function testIsEqualNode()
+ {
+ $dom = new Document;
+ $dom->loadXML('');
+
+ $this->assertTrue($dom->firstOf('//x')->firstChild->isEqualNode($dom->firstOf('//x')->lastChild));
+ $this->assertFalse($dom->firstOf('//x')->firstChild->isEqualNode($dom->firstOf('//y')));
+ }
}
\ No newline at end of file
diff --git a/tests/CommentTest.php b/tests/CommentTest.php
index 1c5f3b8..d816940 100644
--- a/tests/CommentTest.php
+++ b/tests/CommentTest.php
@@ -81,4 +81,13 @@ public function testQuery()
$this->assertEquals('z', $dom->firstOf('//comment()')->query('.//following-sibling::x')->item(0)->getAttribute('id'));
}
+
+ public function testIsEqualNode()
+ {
+ $dom = new Document;
+ $dom->loadXML('');
+
+ $this->assertTrue($dom->firstOf('//x')->firstChild->isEqualNode($dom->firstOf('//x')->lastChild));
+ $this->assertFalse($dom->firstOf('//x')->firstChild->isEqualNode($dom->firstOf('//y')->firstChild));
+ }
}
\ No newline at end of file
diff --git a/tests/DocumentFragmentTest.php b/tests/DocumentFragmentTest.php
index 82b6fa9..1b823bb 100644
--- a/tests/DocumentFragmentTest.php
+++ b/tests/DocumentFragmentTest.php
@@ -83,4 +83,17 @@ public function testQuery()
$this->assertEquals('xx', $fragment->query('x')->item(0)->getAttribute('value'));
}
+
+ public function testIsEqualNode()
+ {
+ $dom = new Document;
+
+ $frag1 = $dom->createDocumentFragment();
+ $frag2 = $dom->createDocumentFragment();
+ $frag1->appendElement('x')->setAttribute('value', 'xx');
+ $frag2->appendElement('x')->setAttribute('value', 'xx');
+ $this->assertTrue($frag1->isEqualNode($frag2));
+ $frag2->appendElement('x');
+ $this->assertFalse($frag1->isEqualNode($frag2));
+ }
}
\ No newline at end of file
diff --git a/tests/DocumentTest.php b/tests/DocumentTest.php
index 03366af..a049915 100644
--- a/tests/DocumentTest.php
+++ b/tests/DocumentTest.php
@@ -244,4 +244,15 @@ public static function getClassMapsTestCases(): array
],
];
}
+
+ public function testIsEqualNode()
+ {
+ $dom1 = new Document;
+ $dom1->loadXML('');
+ $dom2 = new Document;
+ $dom2->loadXML('');
+ $this->assertTrue($dom1->isEqualNode($dom2));
+ $dom2->loadXML('');
+ $this->assertFalse($dom1->isEqualNode($dom2));
+ }
}
\ No newline at end of file
diff --git a/tests/ElementTest.php b/tests/ElementTest.php
index 358e705..415f894 100644
--- a/tests/ElementTest.php
+++ b/tests/ElementTest.php
@@ -17,6 +17,7 @@
#[CoversClass('s9e\SweetDOM\NodeTraits\ChildNodeWorkarounds')]
#[CoversClass('s9e\SweetDOM\NodeTraits\DeprecatedMethods')]
#[CoversClass('s9e\SweetDOM\NodeTraits\MagicMethods')]
+#[CoversClass('s9e\SweetDOM\NodeTraits\NodePolyfill')]
#[CoversClass('s9e\SweetDOM\NodeTraits\ParentNodePolyfill')]
#[CoversClass('s9e\SweetDOM\NodeTraits\ParentNodeWorkarounds')]
#[CoversClass('s9e\SweetDOM\NodeTraits\XPathMethods')]
diff --git a/tests/NodeComparatorTest.php b/tests/NodeComparatorTest.php
new file mode 100644
index 0000000..1ecf140
--- /dev/null
+++ b/tests/NodeComparatorTest.php
@@ -0,0 +1,443 @@
+assertSame($expected, NodeComparator::isEqualNode($node, $otherNode));
+ if ($compareNative ?? version_compare(PHP_VERSION, '8.3.0', '>='))
+ {
+ $this->assertSame($expected, $node->isEqualNode($otherNode), 'Does not match ext/dom');
+ }
+ }
+
+ #[DataProvider('getIsEqualNodeCases')]
+ public function testIsEqualNode(bool $expected, string $xml1, string $xpath1, string $xml2, string $xpath2, bool $compareNative = null): void
+ {
+ $node = $this->getNodeFromXML($xml1, $xpath1);
+ $otherNode = $this->getNodeFromXML($xml2, $xpath2);
+
+ $this->assertIsEqualNode($expected, $node, $otherNode, $compareNative);
+ }
+
+ protected function getNodeFromXML(string $xml, string $query): DOMNode
+ {
+ $dom = new DOMDocument;
+ $dom->loadXML($xml);
+
+ return (new DOMXPath($dom))->query($query)->item(0);
+ }
+
+ public static function getIsEqualNodeCases(): array
+ {
+ return [
+ [
+ true,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//y'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//X'
+ ],
+ [
+ true,
+ '',
+ '//@a',
+ '',
+ '//@a'
+ ],
+ [
+ false,
+ '',
+ '//@a',
+ '',
+ '//@a'
+ ],
+ [
+ false,
+ '',
+ '//@a',
+ '',
+ '//@b'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//*'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ true,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ true,
+ '',
+ '//x',
+ '',
+ '//x',
+ version_compare(PHP_VERSION, '8.3.2', '>=')
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ true,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ true,
+ '',
+ '//x',
+ '',
+ '//x',
+ version_compare(PHP_VERSION, '8.3.2', '>=')
+ ],
+ [
+ false,
+ '',
+ '//y',
+ '',
+ '//*/*'
+ ],
+ [
+ true,
+ '',
+ '//y',
+ '',
+ '//*/*'
+ ],
+ [
+ true,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ true,
+ '..',
+ '//x',
+ '..',
+ '//x'
+ ],
+ [
+ true,
+ '...',
+ '//x',
+ '...',
+ '//x'
+ ],
+ [
+ true,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ false,
+ '...',
+ '//x',
+ '._.',
+ '//x'
+ ],
+ [
+ false,
+ '...',
+ '//x',
+ '..',
+ '//x'
+ ],
+ [
+ false,
+ '..',
+ '//x',
+ '..',
+ '//x'
+ ],
+ [
+ true,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ true,
+ '',
+ '//comment()',
+ '',
+ '//comment()'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ true,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ true,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ false,
+ '..',
+ '//x',
+ '',
+ '//x'
+ ],
+ [
+ false,
+ '',
+ '//x',
+ '',
+ '//@x'
+ ],
+ ];
+ }
+
+ // https://github.com/php/php-src/blob/master/ext/dom/tests/DOMNode_isEqualNode.phpt
+ public function testIsEqualDocumentNode()
+ {
+ $this->assertIsEqualNode(true, new DOMDocument, new DOMDocument);
+ }
+
+ public function testIsEqualDocumentNodeClone()
+ {
+ $dom1 = new DOMDocument;
+ $dom1->loadXML(<<<'EOT'
+ bartext'>
+ '>
+
+ ]>
+
+
+ ...
+
+
+ EOT);
+ $this->assertIsEqualNode(true, $dom1, clone $dom1);
+ }
+
+ public function testIsEqualDocumentTypeNode()
+ {
+ $dom1 = new DOMDocument;
+ $dom1->loadXML(<<<'EOT'
+ bartext'>
+ '>
+
+ ]>
+
+
+ ...
+
+
+ EOT);
+ $this->assertIsEqualNode(true, $dom1->doctype, $dom1->doctype);
+
+ $dom2 = new DOMDocument;
+ $dom2->loadXML('');
+ $this->assertIsEqualNode(false, $dom1->doctype, $dom2->doctype);
+ $dom2->loadXML('
');
+ $this->assertIsEqualNode(false, $dom1->doctype, $dom2->doctype);
+ $dom2->loadXML('
+ ...
+
+
+ EOT);
+
+ $dom2 = new DOMDocument;
+ $dom2->loadXML(<<<'EOT'
+ bartext'>
+ '>
+ bartext'>
+ ]>
+
+
+ ...
+
+
+ EOT);
+
+ $this->assertIsEqualNode(true, $dom1->doctype->entities->getNamedItem('bar'), $dom2->doctype->entities->getNamedItem('bar'));
+ $this->assertIsEqualNode(false, $dom1->doctype->entities->getNamedItem('bar'), $dom2->doctype->entities->getNamedItem('barbar'));
+ $this->assertIsEqualNode(false, $dom1->doctype->entities->getNamedItem('bar'), $dom2->doctype->entities->getNamedItem('foo'));
+ $this->assertIsEqualNode(false, $dom1->doctype->entities->getNamedItem('foo'), $dom2->doctype->entities->getNamedItem('bar'));
+ $this->assertIsEqualNode(false, $dom1->doctype->entities->getNamedItem('foo'), $dom2->doctype->entities->getNamedItem('barbar'));
+ $this->assertIsEqualNode(true, $dom1->doctype->entities->getNamedItem('foo'), $dom2->doctype->entities->getNamedItem('foo'));
+ }
+
+ public function testIsEqualEntityNotationNode()
+ {
+ $dom1 = new DOMDocument;
+ $dom1->loadXML(<<<'EOT'
+ bartext'>
+ '>
+
+ ]>
+
+
+ ...
+
+
+ EOT);
+
+ $dom2 = new DOMDocument;
+ $dom2->loadXML(<<<'EOT'
+
+
+
+ ]>
+ ...
+ EOT);
+
+ $this->assertIsEqualNode(true, $dom1->doctype->notations->getNamedItem('myNotation'), $dom2->doctype->notations->getNamedItem('myNotation'));
+ $this->assertIsEqualNode(false, $dom1->doctype->notations->getNamedItem('myNotation'), $dom2->doctype->notations->getNamedItem('myNotation2'));
+ $this->assertIsEqualNode(false, $dom1->doctype->notations->getNamedItem('myNotation'), $dom2->doctype->notations->getNamedItem('myNotation3'));
+ }
+
+ public function testIsEqualDocumentFragmentNode()
+ {
+ $xml = '';
+
+ $dom = new DOMDocument;
+ $frag1 = $dom->createDocumentFragment();
+ $frag2 = $dom->createDocumentFragment();
+ $frag3 = $dom->createDocumentFragment();
+ $frag4 = $dom->createDocumentFragment();
+
+ $frag1->appendXML($xml);
+ $frag2->appendXML($xml);
+ $frag3->appendXML('');
+ $frag4->appendXML('');
+
+ $this->assertIsEqualNode(true, $frag1, $frag2);
+ $this->assertIsEqualNode(false, $frag1, $frag3);
+ $this->assertIsEqualNode(false, $frag1, $frag4);
+ }
+}
\ No newline at end of file