Невозможно создать пустое значение в узле XML

Я пытаюсь добавить дочерний элемент в узел XML

$rel->appendChild($domtree->createElement('title',NULL));

Я хочу, чтобы это выглядело так

<title></title>

Но я получил это вместо

<title/>

Как создать это с пустым значением?

2 ответа

Решение

Вам нужно явно добавить пустой текстовый узел:

$title = $domtree->createElement('title');
$title->appendChild($domtree->createTextNode(''));
$rel->appendChild($title);

Второй аргумент createElement() это нестандартно, и я лично не использую его, потому что это может привести к немного не интуитивному поведению, как это.

Вы всегда должны создавать текстовые узлы явно на мой взгляд. Другая причина для этого состоит в том, что текстовые узлы автоматически обрабатывают экранирование правильно, в отличие от нестандартного второго аргумента, который требует, чтобы вы вручную экранировали текстовые данные.

Для дальнейшего использования, вот как вы можете легко построить свой xml из массива (включая пустые элементы):

class Test {
    public function getTestXml()
    {
        $testElements = [
            'foo' => 'foo',
            'bar' => 'bar',
            'baz' => [
                'empty' => null,
            ],
        ];

        $xml = new \DOMDocument('1.0', 'UTF-8');
        $test = $this->buildXmlNodeFromArray($xml, 'test', $testElements);

        $xml->appendChild($test);

        return $xml->saveXml();
    }

    /* Here's where all the magic happens */
    private function buildXmlNodeFromArray(\DOMDocument $document, $nodeName, array $nodeElements)
    {
        $node = $document->createElement($nodeName);

        foreach ($nodeElements as $key => $value) {
            if (null === $value || '' === $value) {
                $emptyValue = $document->createTextNode('');
                $emptyElement = $document->createElement($key);
                $emptyElement->appendChild($emptyValue);

                $node->appendChild($emptyElement);
            } elseif (is_array($value)) {
                $subNode = $this->buildXmlNodeFromArray($document, $key, $value);

                $node->appendChild($subNode);
            } else {
                $node->appendChild($document->createElement($key, $value));
            }
        }

        return $node;
    }
}

$test = new Test();

echo $test->getTestXml();

Результат:

<?xml version="1.0" encoding="UTF-8"?>
<test>
    <foo>foo</foo>
    <bar>bar</bar>
    <baz>
       <empty></empty>
    </baz>
</test>
Другие вопросы по тегам