[PHP] Changer la valeur des nœuds d'un document XML

Publié le 18/07/2019 • Actualisé le 18/07/2019


English language detected! 🇬🇧

  We noticed that your browser is using English. Do you want to read this post in this language?

Read the english version 🇬🇧 Close

J'oublie toujours comment faire ! 🤔 Nous chargeons le XML avec un objet DOMDocument, ensuite nous accédons aux nœuds à modifier en utilisant un objet DOMXpath. Il y a bien sûr d'autres moyens d'y arriver. Jetez un coup d'œil à la documentation PHP.


<?php

declare(strict_types=1);

namespace App\Controller\Snippet;

/**
 * J'utilise un trait PHP afin d'isoler chaque snippet dans un fichier.
 * Ce code doit être apellé d'un contrôleur Symfony étendant AbstractController (depuis Symfony 4.2)
 * ou Symfony\Bundle\FrameworkBundle\Controller\Controller (Symfony <= 4.1).
 * Les services sont injectés dans le constructeur du contrôleur principal.
 */
trait Snippet32Trait
{
    /**
     * Code for snippet 32.
     */
    public function snippet32(): void
    {
        $xml = <<<XML
<?xml version="1.0" encoding="iso-8859-1"?>
<data>
  <Id>123456</Id>
  <Email>example@example.com</Email>
  <Login>MrExample</Login>
  <Birthday>1979-01-01</Birthday>
</data>
XML;

        $dom = new \DOMDocument();
        $dom->preserveWhiteSpace = false;
        $dom->loadXML($xml);
        $dom->formatOutput = true;
        echo $dom->saveXML();

        // Remove values of some nodes...
        $nodes = (new \DOMXPath($dom))->query('//Login|//Birthday');
        if (!$nodes instanceof \DOMNodeList) {
            throw new \RuntimeException('Nodes not found.');
        }

        /** @var \DOMElement $node */
        foreach ($nodes as $node) {
            $node->nodeValue = '';
        }

        echo PHP_EOL.$dom->saveXML(); // That's it! 😁
    }
}

 Exécuter le snippet  ≪ this.showUnitTest ? this.trans.hide_unit_test : this.trans.show_unit_test ≫  Plus sur Stackoverflow  Snippet aléatoire

  Travaillez avec moi !

<?php

declare(strict_types=1);

namespace App\Tests\Integration\Controller\Snippets;

use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @see Snippet32Trait
 */
final class Snippet32Test extends KernelTestCase
{
    /**
     * @see Snippet32Trait::snippet32
     */
    public function testSnippet32(): void
    {
        $xml = <<<EOD
<?xml version="1.0" encoding="iso-8859-1"?>
<data>
  <Id>12345689</Id>
  <Email>example@example.com</Email>
  <Login>MrExample</Login>
  <Birthday>1979-01-01</Birthday>
</data>
EOD;

        $nodesPath = '//Login|//Birthday';
        $dom = new \DOMDocument();
        $dom->preserveWhiteSpace = false;
        $dom->loadXML($xml);

        $nodes = (new \DOMXPath($dom))->query($nodesPath);
        if (!$nodes instanceof \DOMNodeList) {
            throw new \RuntimeException('No nodes found.');
        }

        /** @var \DOMElement $node */
        foreach ($nodes as $node) {
            self::assertNotEmpty($node->nodeValue);
        }

        /** @var \DOMElement $node */
        foreach ($nodes as $node) {
            $node->nodeValue = '';
        }

        /** @var \DOMElement $node */
        foreach ($nodes as $node) {
            self::assertEmpty($node->nodeValue);
        }
    }
}