Reputation: 111
So I have the following XML chain:
$xml->assessment->outcomes_processing->outcomes->decvar->attributes()->cutvalue
XML example In Some XML-files $xml->assessment->outcomes_processing->outcomes->... does exist. But here only $xml->assessment exist.
<questestinterop>
<assessment ident="nedolat78356769204914" title="welkom woordenschat 4">
<qtimetadata>
<qtimetadatafield>
<fieldlabel>qmd_assessmenttype</fieldlabel>
<fieldentry>Assessment</fieldentry>
</qtimetadatafield>
</qtimetadata>
<section ident="nedolat78356769204915" title="Woordenschat">
<selection_ordering>
<selection/>
<order order_type="Sequential"/>
</selection_ordering>
<item ident="QTIEDIT:FIB:34932158" title="Oefening 1">
...
</item>
</section>
</assessment>
</questestinterop>
At the moment I am receiving the error: "Trying to get property of non-object". Which is logic because the node from outcomes doesn't exist.
So I tried a solution with isset() which obviously isn't working either.
isset($xml->assessment->outcomes_processing->outcomes->decvar->attributes()->cutvalue) ? ... : null
This gives me the same error. Because the node outcomes doesn't exist, so he throws me the error immediately. The solution could be for checking each node individually with isset(), of course with a function because otherwise I have a lot of checking to do...
This is my function, which is failed to work because the string '->' could not be processed as php code:
// xml: xml structure form SimpleXML
// chain: assessment->outcomes_processing->outcomes->decvar->attributes()->cutvalue
function checkIfXMLChainExists($xml, $chain) {
$xmlChain = '';
$i = 0;
$nodes = explode('->', $chain);
$numItems = count($nodes);
// experimenting with eval() to treat '->' as ->; failed to work
$a = '$xml->assessment->outcomes_processing';
$t = eval($a);
echo $t;
print_r($t);
foreach ($nodes as $node) {
$xmlChain .= '->' . $node;
if (isset($xml->$xmlChain)) { // Node exists
if ($i+1 == $numItems) {
return $xml->$xmlChain;
}
} else { // Node does not exists
return 'does not exist';
}
$i++;
}
Does anyone has some ideas because I don't have any inspiration at the moment :(
Thanks in advance
Upvotes: 0
Views: 409
Reputation: 88697
Returns the data referenced by the chain, or NULL
if it doesn't exist.
function getDataIfExists () {
// We accept an unknown number of arguments
$args = func_get_args();
if (!count($args)) {
trigger_error('getDataIfExists() expects a minimum of 1 argument', E_USER_WARNING);
return NULL;
}
// The object we are working with
$baseObj = array_shift($args);
// Check it actually is an object
if (!is_object($baseObj)) {
trigger_error('getDataIfExists(): first argument must be an object', E_USER_WARNING);
return NULL;
}
// Loop subsequent arguments, check they are valid and get their value(s)
foreach ($args as $arg) {
$arg = (string) $arg;
if (substr($arg, -2) == '()') { // method
$arg = substr($arg, 0, -2);
if (!method_exists($baseObj, $arg)) return NULL;
$baseObj = $baseObj->$arg();
} else { // property
if (!isset($baseObj->$arg)) return NULL;
$baseObj = $baseObj->$arg;
}
}
// If we get here $baseObj will contain the item referenced by the supplied chain
return $baseObj;
}
// Call it like this:
$subObj = getDataIfExists($xml, 'assessment', 'outcomes_processing', 'outcomes', 'decvar', 'attributes()', 'cutvalue');
Upvotes: 1