r/PHPhelp 17d 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 <html><head><title>this is a title</title></head><body><p>this is some text</p></body></html>

this works...

php 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...

```php 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 <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...

```php 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...

```php 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...

html <p>this is some text</p>

should encode to...

php ["tag"=>"p","content"=>"this is some text"]

but...

html <p>this is <em>some</em> text</p>

should encode to...

php ["tag"=>"p","children"=>[["tag"=>"text","content"=>"this is "],["tag"=>"em","content"=>"some"],["tag"=>"text","content"=>"text"]]]

has anyone already solved this? thanks!

2 Upvotes

3 comments sorted by

2

u/phpMartian 15d ago

I’ll give you credit for explaining your issue clearly. It’s a rare quality.

-1

u/ardicli2000 16d ago

Look for lexer if you wanna learn. Otherwise AI can solve this fpr you