# SimpleXML->children() and text nodes

- Thread: https://externals.io/message/7442
- Original archive: https://news-web.php.net/php.internals/7442
- Started by Derick Rethans on 2004-01-31T23:47:17+00:00
- Messages: 5
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #7442 — Derick Rethans — 2004-01-31T23:47:17+00:00

URL: https://externals.io/message/7442#7442

Hello,

I was wondering on how to iterate over the elements of <body> in
the following piece of XML:

<sx>
<body>
  <element>foo</element>
  bar
  <baz>foobar</baz>
</body>
</sx>

when I iterate over $s->body->children() I only get the <element/> and
the <baz/>. Shouldn't it also show the text nodes?

Another thing that would be useful to have is a tag() method, so that
this would work too: (ie, I can check what tag I got during iteration).

<?php
  foreach ($sx->body->children() as $node) {
    if ($node->tag() == 'element') {
      /* do this */
    }
  }
?>

or can I do that in a different way now?


regards,
Derick

---

## #7443 — Adam Maccabee Trachtenberg — 2004-02-01T00:27:32+00:00

URL: https://externals.io/message/7442#7443 · In reply to: #7442

> when I iterate over $s->body->children() I only get the <element/> and
> the <baz/>. Shouldn't it also show the text nodes?

I hestitate to get back into this discussion, but I will give you the
answers as best I can. :)

The SimpleXML model prefers you to not mix element and text nodes
side-by-side. You can, and it won't complain, but (IMHO) the theory is
that an element should either contain other elements or a single text
(or CDATA) node. This is a more "XML-centric" viewpoint towards data
than an "HTML-centric" perspective. (Realize these are generalizations
here about the nature of XML and HTML.)

If you're interested in accessing the XML inside $sx->body, you can
either call $sx->body->asXML(), which will give it to you as a string,
or use DOM. :)

> Another thing that would be useful to have is a tag() method, so that
> this would work too: (ie, I can check what tag I got during iteration).
>
> <?php
>   foreach ($sx->body->children() as $node) {
>     if ($node->tag() == 'element') {
>       /* do this */
>     }
>   }
> ?>
>
> or can I do that in a different way now?

AFAIK, you're generally expected to have an idea of your document's
schema when using SimpleXML. (Alternatively, it's easier to use
SimpleXML when you know the document's schema.)

There's no tag() method, but you can always do:

// My personal favorite
if (isset($node->element)) {
  /* do this */
}

Or:

if ($node->xpath('/element')) {
  /* do this */
}

Or:

$dom = new domDocument;
$dom->import_simplexml($sx);
/* DOM code here */

SimpleXML doesn't really have a good set of intraspection methods
because it's a slippery slope and that ugliness is better left to the
DOM extension. That's the party line, AFAIK.

BTW, I promise in advance to completely retract any or all of my
comments if Sterling, Marcus, or Rob contradict me. :)

-adam

-- 
adam@trachtenberg.com
author of o'reilly's php cookbook
avoid the holiday rush, buy your copy today!

---

## #7452 — Tobias Bradtke — 2004-02-01T09:57:38+00:00

URL: https://externals.io/message/7442#7452 · In reply to: #7442

Derick Rethans wrote:

> Another thing that would be useful to have is a tag() method, so that
> this would work too: (ie, I can check what tag I got during iteration).
> 
> <?php
>   foreach ($sx->body->children() as $node) {
>     if ($node->tag() == 'element') {
>       /* do this */
>     }
>   }
> ?>
> 
> or can I do that in a different way now?

this works:

foreach ($sxe->body as $node) {
  if (dom_import_simplexml($node)->tagName == 'element') {
    echo "element";
    }
  }

but i don't know how much overhead the conversion from simplexml to dom
takes..


webwurst

---

## #7458 — Marcus Boerger — 2004-02-01T15:01:28+00:00

URL: https://externals.io/message/7442#7458 · In reply to: #7442

Hello Derick,

Sunday, February 1, 2004, 12:47:17 AM, you wrote:

> Hello,

> I was wondering on how to iterate over the elements of <body> in
> the following piece of XML:

> <sx>
> <body>
>   <element>foo</element>
>   bar
>   <baz>foobar</baz>
> </body>
> </sx>

> when I iterate over $s->body->children() I only get the <element/> and
> the <baz/>. Shouldn't it also show the text nodes?

> Another thing that would be useful to have is a tag() method, so that
> this would work too: (ie, I can check what tag I got during iteration).

> <?php
>   foreach ($sx->body->children() as $node) {
>     if ($node->tag() == 'element') {
>       /* do this */
>     }
>   }
?>>

> or can I do that in a different way now?


Have a go with classes SimpleXMLIterator and RecursiveIteratorIterator
from SPL:

foreach(new RecursiveIteratorIterator(new SimpleXMLIterator($xml_string)) as
$node) {
    /* do whatever */
}


-- 
Best regards,
 Marcus                            mailto:helly@php.net

---

## #7543 — Rob Richards — 2004-02-04T14:46:31+00:00

URL: https://externals.io/message/7442#7543 · In reply to: #7443

Adam's pretty much correct with his statements on this.

The children() method's real purpose is for using namespaces within the
document.
Without an argument, it retrieves child elements within the default
namespace, otherwise it will retrieve elements within the namespace passed
in. It also sets the namespace scope for the sxe object.

nsuri is considered to be the namespace uri in the following example:.

$children = $sxe->children("nsuri");
$myelement = $children[0]->myelement;

The call to $children[0]->mylement will retrieve the myelement child nodes
within the nsuri namespace (since $children is set to the nsuri scope).

The same pretty much hodls true for attributes() as well.

Rob


From: Adam Maccabee Trachtenberg


> 
>
> > […]

> The SimpleXML model prefers you to not mix element and text nodes
> side-by-side. You can, and it won't complain, but (IMHO) the theory is
> that an element should either contain other elements or a single text
> (or CDATA) node. This is a more "XML-centric" viewpoint towards data
> than an "HTML-centric" perspective. (Realize these are generalizations
> here about the nature of XML and HTML.)
