Skip to content

Commit 2aa54e0

Browse files
committed
Fix mutable nodeList reference during traversal
1 parent 6123139 commit 2aa54e0

File tree

3 files changed

+50
-3
lines changed

3 files changed

+50
-3
lines changed

src/Xml/Dom/Traverser/Traverser.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use DOMNode;
88
use function VeeWee\Xml\Dom\Locator\Attribute\attributes_list;
9+
use function VeeWee\Xml\Dom\Locator\Node\children;
910

1011
final class Traverser
1112
{
@@ -30,7 +31,7 @@ public function traverse(DOMNode $node): DOMNode
3031
$this->traverse($attribute);
3132
}
3233

33-
foreach ($node->childNodes as $child) {
34+
foreach (children($node) as $child) {
3435
$this->traverse($child);
3536
}
3637

src/Xml/ErrorHandling/detect_issues.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace VeeWee\Xml\ErrorHandling;
66

7-
use LibXMLError;
87
use Psl\Result;
98
use Psl\Result\ResultInterface;
109

@@ -31,7 +30,6 @@ function detect_issues(callable $run): array
3130

3231
$result = Result\wrap($run(...));
3332

34-
/** @var list<LibXMLError> $errors */
3533
$errors = libxml_get_errors();
3634
libxml_clear_errors();
3735
libxml_use_internal_errors($previousErrorReporting);

tests/Xml/Dom/Traverser/TraverserTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use VeeWee\Xml\Dom\Traverser\Traverser;
1212
use VeeWee\Xml\Dom\Traverser\Visitor\AbstractVisitor;
1313
use function VeeWee\Xml\Dom\Builder\attribute;
14+
use function VeeWee\Xml\Dom\Configurator\comparable;
1415
use function VeeWee\Xml\Dom\Locator\document_element;
1516
use function VeeWee\Xml\Dom\Mapper\xml_string;
1617
use function VeeWee\Xml\Dom\Predicate\is_attribute;
@@ -130,4 +131,51 @@ public function onNodeLeave(DOMNode $node): Action
130131

131132
static::assertXmlStringEqualsXmlString($doc->toXmlString(), '<hello enter="yes" leave="yes" />');
132133
}
134+
135+
136+
public function test_it_can_recursively_remove_empty_nodes(): void
137+
{
138+
$doc = Document::fromXmlString(
139+
<<<EOXML
140+
<movies>
141+
<movie>
142+
<name>Terminator</name>
143+
<genre>
144+
<action />
145+
<romance />
146+
</genre>
147+
<prices>
148+
<oscar />
149+
</prices>
150+
</movie>
151+
</movies>
152+
EOXML
153+
);
154+
155+
$transformedNode = $doc->traverse(new class extends AbstractVisitor {
156+
public function onNodeLeave(DOMNode $node): Action
157+
{
158+
if (!is_element($node)) {
159+
return new Action\Noop();
160+
}
161+
162+
if (trim($node->textContent) !== '') {
163+
return new Action\Noop();
164+
}
165+
166+
return new Action\RemoveNode();
167+
}
168+
});
169+
170+
$actual = Document::fromXmlNode($transformedNode, comparable());
171+
$expected = Document::fromXmlString(<<<EOXML
172+
<movies>
173+
<movie>
174+
<name>Terminator</name>
175+
</movie>
176+
</movies>
177+
EOXML, comparable());
178+
179+
static::assertSame($actual->toXmlString(), $expected->toXmlString());
180+
}
133181
}

0 commit comments

Comments
 (0)