|
11 | 11 | use VeeWee\Xml\Dom\Traverser\Traverser; |
12 | 12 | use VeeWee\Xml\Dom\Traverser\Visitor\AbstractVisitor; |
13 | 13 | use function VeeWee\Xml\Dom\Builder\attribute; |
| 14 | +use function VeeWee\Xml\Dom\Configurator\comparable; |
14 | 15 | use function VeeWee\Xml\Dom\Locator\document_element; |
15 | 16 | use function VeeWee\Xml\Dom\Mapper\xml_string; |
16 | 17 | use function VeeWee\Xml\Dom\Predicate\is_attribute; |
17 | 18 | use function VeeWee\Xml\Dom\Predicate\is_element; |
| 19 | +use function VeeWee\Xml\Dom\Predicate\is_empty_node; |
18 | 20 | use function VeeWee\Xml\Dom\Predicate\is_non_empty_text; |
19 | 21 | use function VeeWee\Xml\Dom\Predicate\is_whitespace; |
20 | 22 |
|
@@ -130,4 +132,50 @@ public function onNodeLeave(DOMNode $node): Action |
130 | 132 |
|
131 | 133 | static::assertXmlStringEqualsXmlString($doc->toXmlString(), '<hello enter="yes" leave="yes" />'); |
132 | 134 | } |
| 135 | + |
| 136 | + /** @test */ |
| 137 | + public function it_can_recursively_remove_empty_nodes(): void |
| 138 | + { |
| 139 | + $doc = Document::fromXmlString(<<<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 | + self::assertSame($actual->toXmlString(), $expected->toXmlString()); |
| 180 | + } |
133 | 181 | } |
0 commit comments