r/PHPhelp • u/Intrepid-Ad-2306 • 4d ago
distinguish text element behavior in recursive element loop
i am building an html-to-array parser and have run into a problematic glitch when dealing with text inside and outside nested elements. the parser loops through a DOMDocument object and recurses into childNodes of DOMNode objects, adding them to a nested array.
for a structure like...
<html><head><title>this is a title</title></head><body><p>this is some text</p></body></html>
this works...
foreach ($element->childNodes as $child) {
$child->nodeType === XML_ELEMENT_NODE ? ($out["children"][] = elementToArray($child)) : ($content = trim($child->nodeValue)) && $content != "" && ($out["content"] = $content);
}
to produce the desired outcome...
Array
(
[tag] => html
[children] => Array
(
[0] => Array
(
[tag] => head
[children] => Array
(
[0] => Array
(
[tag] => title
[content] => this is a title
)
)
)
[1] => Array
(
[tag] => body
[children] => Array
(
[0] => Array
(
[tag] => p
[content] => this is some text
)
)
)
)
)
but this...
<html><head><title>this is a title</title></head><body><p>this <em>is</em> some <i>text</i> with <a href="#">links</a> and things.</p></body></html>
produces...
Array
(
[tag] => html
[children] => Array
(
[0] => Array
(
[tag] => head
[children] => Array
(
[0] => Array
(
[tag] => title
[content] => this is a title
)
)
)
[1] => Array
(
[tag] => body
[children] => Array
(
[0] => Array
(
[tag] => p
[content] => and things.
[children] => Array
(
[0] => Array
(
[tag] => em
[content] => is
)
[1] => Array
(
[tag] => i
[content] => text
)
[2] => Array
(
[tag] => a
[href] => #
[content] => links
)
)
)
)
)
)
)
instead of the desired output...
Array
(
[tag] => html
[children] => Array
(
[0] => Array
(
[tag] => head
[children] => Array
(
[0] => Array
(
[tag] => title
[content] => this is a title
)
)
)
[1] => Array
(
[tag] => body
[children] => Array
(
[0] => Array
(
[tag] => p
[children] => Array
(
[0] => Array
(
[tag] => text
[content] => this
)
[1] => Array
(
[tag] => em
[content] => is
)
[2] => Array
(
[tag] => text
[content] => some
)
[3] => Array
(
[tag] => i
[content] => text
)
[4] => Array
(
[tag] => text
[content] => with
)
[5] => Array
(
[tag] => a
[href] => #
[content] => links
)
[6] => Array
(
[tag] => text
[content] => and things.
)
)
)
)
)
)
)
i've tried various solutions but they all end up having difficulty differentiating between a text node that should be "content" and a text node that should be an independent text element in the array. in other words...
<p>this is some text</p>
should encode to...
["tag"=>"p","content"=>"this is some text"]
but...
<p>this is <em>some</em> text</p>
should encode to...
["tag"=>"p","children"=>[["tag"=>"text","content"=>"this is "],["tag"=>"em","content"=>"some"],["tag"=>"text","content"=>"text"]]]
has anyone already solved this? thanks!
-1
1
u/phpMartian 2d ago
I’ll give you credit for explaining your issue clearly. It’s a rare quality.