Edit report at http://bugs.php.net/bug.php?id=39593&edit=1

 ID:                 39593
 Comment by:         rodolphe at metaphores dot ch
 Reported by:        dave dot lane at gmx dot net
 Summary:            XPath NodeList: "Couldn't fetch DOMElement: Node no
                     longer exists"
 Status:             Wont fix
 Type:               Bug
 Package:            DOM XML related
 Operating System:   Linux
 PHP Version:        5.2.0
 Block user comment: N

 New Comment:

Hello,



Is there a way to determine if the node is no longer linked to his xml
structure without having a warning ?



Thx


Previous Comments:
------------------------------------------------------------------------
[2006-11-22 20:53:42] dave dot lane at gmx dot net

OK excellent, thanks for the tip. It makes sense and I did suspect it
had something to do with scope, I thought it was the NodeList that was
causing the problem though.



I think this should be documented though.

------------------------------------------------------------------------
[2006-11-22 19:06:06] rricha...@php.net

The problem is that you are working with a fragment that's not attached
to the document and only have a reference to a node deep within the
fragment rather than to the top element of the fragment. When the object
holding the fragment ($NodeImported) goes out of scope, the whole
fragment is destroyed - as there isn't a way to track fragments without
introducing way too much overhead. You still have the DOMElement object,
just not the underlying xml data structure.



you either need to return the entire fragment from the function call or
remove the nodes you want to return from the  fragment within the
array.



i.e. within the foreach() loop add:

$Node->parentNode->removeChild($Node);



This behavior while not optimal is a necessary evil to prevent leaking
memory while also keeping system memory usage and performance at an
acceptable level when using the DOM extension.

------------------------------------------------------------------------
[2006-11-22 17:58:31] dave dot lane at gmx dot net

Sorry description should read:



Description:

------------

When the nodes in a NodeList that is the result of an XPath query are
copied into an array and returned from a function the Nodes in the array
although they exist are not valid. When the nodes in the array are used
a warning results: "Couldn't fetch DOMElement. Node no longer exists..."

------------------------------------------------------------------------
[2006-11-22 17:54:18] dave dot lane at gmx dot net

Description:
------------
The following code does not work. When the nodes in a NodeList that is
the result of an XPath query are copied into an array and returned from
a function. When the nodes in the array are used a warning results:
"Couldn't fetch DOMElement. Node no longer exists..."

Reproduce code:
---------------
bug.php:

<?

$DOMMain =& OpenXMLDoc('main.xml');



$aArray =& GetArray($DOMMain);

echo 'After return: '.$aArray[0]->localName->localName."<br>\n";



function &OpenXMLDoc($sFileName) {

        $DOM = new DOMDocument();

        $DOM->preserveWhiteSpace = false;

        $DOM->load($sFileName);

        return $DOM;

}



function &ExecuteXPath($sXPath, DOMDocument &$DOMDocument, DOMNode
&$DOMNode) {

        $objXPath = new DOMXPath($DOMDocument);

        return $objXPath->query($sXPath, $DOMNode);

}



function &GetArray(&$DOMMain) {

        $DOMInclude =& OpenXMLDoc('include.xml');



        $NodeImported =
$DOMMain->importNode($DOMInclude->documentElement, true);

        $NodeListImported =& ExecuteXPath('./include1', $DOMMain,
$NodeImported);

        $NodeListImported = $NodeListImported->item(0)->childNodes;



        echo 'In NodeList:
'.$NodeListImported->item(0)->localName."<br>\n";



        $aArray = array();

        foreach($NodeListImported as $Node) {

                $aArray[] = $Node;

        }

        echo 'In Array: '.$aArray[0]->localName."<br>\n";

        return $aArray;

}



?>



main.xml:

<?xml version = "1.0" encoding="ISO-8859-1"?>

<root>

</root>



include.xml:

<?xml version = "1.0" encoding="ISO-8859-1"?>

<include>

        <include1>

                <div>

                        <span>test</span>

                </div>

        </include1>

</include>



Expected result:
----------------
In NodeList: div

In Array: div

After return: div



Actual result:
--------------
In NodeList: div

In Array: div



Warning: Couldn't fetch DOMElement. Node no longer exists in
/var/www/html/usr/dla/csc/V2/bug/bug.php on line 5

After return:




------------------------------------------------------------------------



-- 
Edit this bug report at http://bugs.php.net/bug.php?id=39593&edit=1

Reply via email to