如何在PHP中从XML中删除实体声明

I'm trying to remove <!ENTITY definitions from a XML file without success, I thought that by using the following snippet the output will contain no traces of entity definitions but I'm wrong.

How can I achieve this goal?

I get no error message beside the DOMDocument::loadXML(): xmlns: URI &ns_svg; is not absolute in Entity

A little context:

I'm embedding an SVG inside another, but the <!ENTITY gives me all kind of problem, so I'm thinking of using LIBXML_NOENT and deleting all the <!ENTITY definitions.

The PHP:

<?php

header('Content-Type: text/plain');
$str = file_get_contents(dirname(__FILE__) . '/test2.svg');



$document = new DOMDocument();
$document->loadXML($str);

foreach ($document->doctype->entities as $entity) {
    $entity->parentNode->removeChild($entity); // I thought this would remove the <!ENTITY declaration
}

echo $document->saveXML(); // --> I want the XML without <!ENTITY ns_svg "http://www.w3.org/2000/svg"> and <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">

The XML:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
    <!ENTITY ns_svg "http://www.w3.org/2000/svg">
    <!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
]>
<svg  version="1.1"
     id="Bundesschild" sodipodi:version="0.32" xmlns:cc="http://web.resource.org/cc/" xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" inkscape:version="0.43" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" sodipodi:docbase="D:\Kuvat\Wikipedia" sodipodi:docname="Flag_of_Germany_(state).svg"
     xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="250" height="275" viewBox="0 0 250 275"
     overflow="visible" enable-background="new 0 0 250 275" xml:space="preserve">
<path id="Schild" fill="#FFCE00" stroke="#000000" d="M235.885,2.558c0,0,0,131.825,0,171.735
    c0,54.121-50.504,98.265-112.501,98.265c-61.996,0-112.5-44.144-112.5-98.265c0-39.91,0-171.735,0-171.735H235.885z"/>
</svg>

The output:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_svg "http://www.w3.org/2000/svg"> <!-- Why this is still here???? -->
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink"> <!-- Why this is still here???? -->
]>
<svg xmlns:cc="http://web.resource.org/cc/" xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" version="1.1" id="Bundesschild" sodipodi:version="0.32" inkscape:version="0.43" sodipodi:docbase="D:\Kuvat\Wikipedia" sodipodi:docname="Flag_of_Germany_(state).svg" width="250" height="275" viewBox="0 0 250 275" overflow="visible" enable-background="new 0 0 250 275" xml:space="preserve">
<path id="Schild" fill="#FFCE00" stroke="#000000" d="M235.885,2.558c0,0,0,131.825,0,171.735  c0,54.121-50.504,98.265-112.501,98.265c-61.996,0-112.5-44.144-112.5-98.265c0-39.91,0-171.735,0-171.735H235.885z"/>
</svg>

You can only remove the whole document type node. The entities does not seem to be child nodes of it. But before that you should substitute the entities using the LIBXML_NOENT:

$document = new DOMDocument();
$document->loadXML($xml, LIBXML_NOENT);

$document->removeChild($document->doctype);

echo $document->saveXML();

The only way to keep the document type I found, was creating a new document with the document type and copy all nodes into it.

$document = new DOMDocument();
$document->loadXML($xml, LIBXML_NOENT);

$existingDocumentType = $document->doctype;
if (NULL !== $existingDocumentType) {
  $implementation = new DOMImplementation;
  $newDocumentType = $implementation->createDocumentType(
    $existingDocumentType->name, 
    $existingDocumentType->publicId, 
    $existingDocumentType->systemId
  );
  $newDocument = $implementation->createDocument(null, null, $newDocumentType);
  foreach ($document->childNodes as $node) {
    $copy = $newDocument->importNode($node, TRUE);
    if ($copy) {
      $newDocument->appendChild($copy);
    }
  }
  $document = $newDocument;
}

echo $document->saveXML();

Document type nodes can not be imported into another document, DOMDcoument::importNode() will return FALSE for it.

If you look at the standard DOMDocumentType::entitites is a DOMNamedNodeMap and should have a method removeNamedItem(). But if you call it PHP outputs:

Warning: DOMNamedNodeMap::removeNamedItem(): Not yet implemented in ... on line ...