I'm having some issues with PHP DOMXML - in particular the
get_elements_by_tagname method. Now, the PGP docs on this are, well,
sparse, so maybe I'm just doing something stupid. I thought this
method would behave like the 'findnodes' XML method in Perl. Namely
that you can pass it an xpath statement and it will find nodes that
match:
$array = $node->get_elements_by_tagname($xpath);
This is long so here's a pagebreak:
And, indeed, this seems to have worked when I've used it in the past.
But I'm working on a more complex system now which does a lot more
sub-node access, etc, and it is failing on me. I put together this
example to demonstrate the failure modes I'm experiencing.
----------------------------------------------------------------------
<?php
if (PHP_OS == "WIN32" || PHP_OS == "WINNT") {
define('EOL', "\r\n");
}
else {
define('EOL', "\n");
}
header("Content-Type: text/plain");
print PHP_VERSION . EOL;
$xml =
'<TestDoc>
<level1>
<level2>
<level3>
<level4>
<fubar>fubar</fubar>
<fubaz>fubaz</fubaz>
</level4>
</level3>
</level2>
</level1>
</TestDoc>';
if (!$domResponse = domxml_open_mem($xml)) {
print("failed!");
}
print pcGetField(&$domResponse, "fubar") . EOL;
lookup(&$domResponse);
function lookup($domResponseRef) {
print $domResponseRef->dump_mem();
$node =
$domResponseRef->get_elements_by_tagname("level4");
$node = $node[0];
print_r($node);
print pcGetField2(&$node, "//fubar") . EOL;
print pcGetField(&$domResponseRef, "fubar") . EOL;
print pcGetField(&$node, "fubar") . EOL;
$node =
$node->get_elements_by_tagname("fubar");
print $node[0]->get_content() . EOL;
$node = $node[0];
print_r($node);
}
function pcGetField($nodeRef, $tag) {
if(!isset($nodeRef)) {
print("pcGetField: node is blank [" . $tag . "]");
return "";
}
$node = $nodeRef->get_elements_by_tagname($tag);
$node = $node[0];
return $node->get_content();
}
function pcGetField2($nodeRef, $tag) {
if(!isset($nodeRef)) {
print("pcGetField: node is blank [" . $tag . "]");
return "";
}
$xpath = xpath_new_context($nodeRef);
$node = &xpath_eval($xpath, $tag);
$node = $node->nodeset[0];
return $node->get_content();
}
?>
----------------------------------------------------------------------
With it like this everything is fine:
----------------------------------------------------------------------
4.2.2
fubar
<?xml version="1.0"?>
<TestDoc>
<level1>
<level2>
<level3>
<level4>
<fubar>fubar</fubar>
<fubaz>fubaz</fubaz>
</level4>
</level3>
</level2>
</level1>
</TestDoc>
DomElement Object
(
[type] => 1
[tagname] => level4
[0] => 3
[1] => 137395784
)
fubar
fubar
fubar
fubar
DomElement Object
(
[type] => 1
[tagname] => fubar
[0] => 2
[1] => 138335176
)
----------------------------------------------------------------------
You see, I'm jumping down to 'level4' so fubar is an immediate child
node. But if I start from *anywhere* except the root node or the
immediate parent, it fails. So if I change:
$node = $domResponseRef->get_elements_by_tagname("level4");
to
$node = $domResponseRef->get_elements_by_tagname("level1");
I get:
----------------------------------------------------------------------
4.2.2
fubar
<?xml version="1.0"?>
<TestDoc>
<level1>
<level2>
<level3>
<level4>
<fubar>fubar</fubar>
<fubaz>fubaz</fubaz>
</level4>
</level3>
</level2>
</level1>
</TestDoc>
DomElement Object
(
[type] => 1
[tagname] => level1
[0] => 3
[1] => 138064304
)
fubar
fubar
<br />
<b>Fatal error</b>: Call to a member function on a non-object in
<b>/home/megazone/scripts/PHP/Kiosk/test.php</b> on line <b>56</b><br />
----------------------------------------------------------------------
Note that the it works when checking from the docroot and later when
using xpath_eval and from the reference to the doc root - but fails
the first time you try it from the subnode. It will fail with
TestDoc, level1, level2, and level3. it will fail if I try
get_elements_by_tagname("fubar"), get_elements_by_tagname("//fubar"),
etc. It also fails if you're at say level3 and try to look for
"level4/fubar". I think I've tried every combination I can think of.
So is this just a limitation that it only works when working with the
root node of the document or when looking for an immediate child of
the current node? What the heck am I not seeing?
Thanks.
-MZ, RHCE #806199299900541, ex-CISSP #3762
--
<URL:mailto:megazoneatmegazone.org> Gweep, Discordian, Author, Engineer, me.
"A little nonsense now and then, is relished by the wisest men" 508-755-4098
<URL:http://www.megazone.org/> <URL:http://www.eyrie-productions.com/> Eris