3

I've been trying to combine two XML documents like this:

$def  = new DOMDocument( '1.0' );
$rdef = new DOMDocument( '1.0' );
$def->load( $path );
$rdef->loadXML( $info );
$r = $def->getElementsByTagName( 'repository' )->item( 0 );
$s = $rdef->getElementsByTagName( 'repository' )->item( 0 );
try {
    $r->appendChild( $s );
}
catch ( DOMException $e ) {
    SPConfig::debOut( get_class( $s ) );
    SPConfig::debOut( $e->getMessage() );
}

The result is:

DOMElement
Wrong Document Error

So it seems to me that $rdef->getElementsByTagName( 'repository' )->item( 0 ) returns DOMElement object but the definition says it should be DOMNode object.

Any idea what is wrong about it?

hakre
  • 193,403
  • 52
  • 435
  • 836
Radek Suski
  • 1,352
  • 1
  • 13
  • 23

1 Answers1

8

Nothing wrong about it. DOMNodeList can hold any DOMNode instances or subclasses thereof. DOMElement extends DOMNode, so technically a DOMElement is a DOMNode as well. Same for DOMAttr.

EDIT: The problem is you trying to copy into the other DOMDocument. You have to importNode the node into the Document first, before appending it.

EDIT2: Try this please:

$r = $def->getElementsByTagName( 'repository' )->item( 0 );
$s = $rdef->getElementsByTagName( 'repository' )->item( 0 );
$i = $def->importNode( $s, TRUE );
$r->appendChild( $i , TRUE );

EDIT3: Full example

$srcXML = <<< XML
<repositories>
    <repository>
        <element>foo</element>
    </repository>
</repositories>
XML;

$destXML = <<< XML
<repositories>
    <repository>
        <element>bar</element>
    </repository>
</repositories>
XML;

$srcDoc  = new DOMDocument;
$destDoc = new DOMDocument;
$destDoc->formatOutput = TRUE;
$destDoc->preserveWhiteSpace = FALSE;

$srcDoc->loadXML( $srcXML );
$destDoc->loadXML( $destXML );

$destNode = $destDoc->getElementsByTagName('repository')->item( 0 );
$srcNode  = $srcDoc->getElementsByTagName('repository')->item( 0 );
$import   = $destDoc->importNode($srcNode, TRUE);
$destNode->parentNode->appendChild($import);
echo $destDoc->saveXML();

gives

<?xml version="1.0"?>
<repositories>
  <repository>
    <element>bar</element>
  </repository>
  <repository>
    <element>foo</element>
  </repository>
</repositories>
Gordon
  • 312,688
  • 75
  • 539
  • 559
  • So the question is, how to cast DOMElement to DOMNode to append it? – Radek Suski Jun 22 '10 at 08:09
  • @Radek you don't have to. Like I said, a DOMElement *is-a* DOMNode through inheritance. Just append it. The problem is you trying to copy into the other DOMDocument. You have to [`importNode`](http://de3.php.net/manual/en/domdocument.importnode.php) the node into the Document first, before appending it. – Gordon Jun 22 '10 at 08:16
  • Tried to import the node with $def->importNode( $s, true ); but still getting the same error. Just wondering if it is not easier to transform these documents into arrays, join these, and then transform back into a XML document :( – Radek Suski Jun 22 '10 at 08:52
  • thank you very much. It works for me. I've been trying to add the $s node instead of the result from importNode. Thanks a lot :) – Radek Suski Jun 22 '10 at 10:36