/    Sign up×
Community /Pin to ProfileBookmark

SimpleXML – referencing iterated members

Hey folks,

I’m at my limits on SimpleXML knowledge. Suppose I have two SimpleXMLElements:

$sessions and $events

$sessions members basically contain FK’s to their parent $event PK’s. And I’d like to put add a reference in the each $event member’s sessions. My initial thought was something like this:

[code=php]foreach ($sessions as $s) {
foreach ($events as $e) {
if ((string)$s->parent_id == (string)$e->id) {
$e->addChild(‘session’, $s);
}
}
}[/code]

The code above ultimately adds “blank” children though — presumably adding a reference to the loop-local $s. And while it seems odd that $s would go out of scope and not $e, the logical solution (in my mind) would be the change the loops:

[code=php]foreach ($sessions as &$s) {
foreach ($events as &$e) {
if ((string)$s->parent_id == (string)$e->id) {
$e->addChild(‘session’, $s);
}
}
}[/code]

No dice again — not allowed: [I]Fatal error: An iterator cannot be used with foreach by reference in …[/I]

Thoughts?

Thanks,

to post a comment
PHP

5 Comments(s)

Copy linkTweet thisAlerts:
@NogDogMay 16.2011 — Maybe you need to cast the element to string in order to get the value?
[code=php]
$e->addChild('session', (string) $s);
[/code]
Copy linkTweet thisAlerts:
@svidgenauthorMay 16.2011 — I guess it didn't even occur to me that addChild explicitly takes a string. Any idea how/if I could add the element from the child structure directly?
Copy linkTweet thisAlerts:
@NogDogMay 16.2011 — Not sure if SimpleXML can do that. I'm pretty sure the DOM classes can, though probably with more work to iterate through the nodes. ?
Copy linkTweet thisAlerts:
@svidgenauthorMay 16.2011 — I always start off with SimpleXML thinking, [I]oh, I just need to do some simple stuff with [B]XML[/B] ...[/I]

Well, thank-you sir.
Copy linkTweet thisAlerts:
@svidgenauthorMay 17.2011 — For the curious mind, I ended up copying elements from one tree to another with the following:

[code=php] function insert_xmlelement(&$simplexml_to, $as, &$simplexml_from) {
// add the base child element
$simplexml_temp = $simplexml_to->addChild($as, (string)$simplexml_from);

// add attributes to the new child
foreach ($simplexml_from->attributes() as $attr_key => $attr_value) {
$simplexml_temp->addAttribute($attr_key, $attr_value);
}

// add subchildren
foreach ($simplexml_from as $k => $v) {
insert_xmlelement($simplexml_temp, $k, $v);
}
} // append_simplexml()[/code]


So, the problem code becomes the following:

[code=php]foreach ($sessions as $s) {
foreach ($events as $e) {
if ((string)$s->parent_id == (string)$e->id) {
insert_xmlelement($e, 'session', $s);
}
}
} [/code]


Probably not the most elegant solution. But, it works. (The current parent-child matching "algorithm" is particularly terrible, running in O(n^2) time.)
×

Success!

Help @svidgen spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.3,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...