Before I start I would like to say I am a noob at reading XML into PHP but I have so far managed to load XML and display the data onto a PHP page. My next test is to group items.
Here is an XML snippet:
<MailboxDatabases>
<MailboxDatabase>
<DatabaseName>DB01</DatabaseName>
<Status>Healthy</Status>
<MailboxServer>MB08</MailboxServer>
<ActiveDatabaseCopy>mb07</ActiveDatabaseCopy>
<ActivationSuspended>False</ActivationSuspended>
<SinglePageRestore>0</SinglePageRestore>
<ContentIndexState>Healthy</ContentIndexState>
<Active>false</Active>
</MailboxDatabase>
<MailboxDatabase>
<DatabaseName>DB01</DatabaseName>
<Status>Healthy</Status>
<MailboxServer>MB07</MailboxServer>
<ActiveDatabaseCopy>mb07</ActiveDatabaseCopy>
<ActivationSuspended>False</ActivationSuspended>
<SinglePageRestore>0</SinglePageRestore>
<ContentIndexState>Healthy</ContentIndexState>
<Active>true</Active>
</MailboxDatabase>
<MailboxDatabases>
<MailboxDatabase>
<DatabaseName>DB02</DatabaseName>
<Status>Healthy</Status>
<MailboxServer>MB08</MailboxServer>
<ActiveDatabaseCopy>mb07</ActiveDatabaseCopy>
<ActivationSuspended>False</ActivationSuspended>
<SinglePageRestore>0</SinglePageRestore>
<ContentIndexState>Healthy</ContentIndexState>
<Active>true</Active>
</MailboxDatabase>
<MailboxDatabase>
<DatabaseName>DB02</DatabaseName>
<Status>Healthy</Status>
<MailboxServer>MB07</MailboxServer>
<ActiveDatabaseCopy>mb07</ActiveDatabaseCopy>
<ActivationSuspended>False</ActivationSuspended>
<SinglePageRestore>0</SinglePageRestore>
<ContentIndexState>Healthy</ContentIndexState>
<Active>false</Active>
</MailboxDatabase>
</MailboxDatabases>
As you can see, "DatabaseName" is the same in two items but "Active" is different. What I want to do is display the above xml in php like
DB01 - MB08 - false | DB01 - MB07 - true
DB02 - MB08 - true | DB01 - MB07 - false
using the following elements (database) - (Mailboxserver) - (active) | ...
Please could someone give me a hand and also please try to explain the code.
Overall strategy:
<DatabaseName>
<MailboxDatabase>
that belong to a group and echo their <MailboxServer>
and <Active>
It's time to learn about selecting certain nodes from an XML, and this is best done with xpath
. In short, xpath
is for XML what SQL is for databases.
Let's say you have a SimpleXML
object ready:
$xml = simplexml_load_string($x); // assume XML in $x
create a list of unique groups
Get all <DatabaseName>
in an array:
$groups = $xml->xpath("/MailboxDatabases/MailboxDatabase/DatabaseName");
$groups
contains an array of SimpleXML
elements now, so let's do some array-magic to transform those into strings:
$groups = array_map("strval", $groups);
Result (var_dump
):
array(4) {
[0]=>
string(4) "DB01"
[1]=>
string(4) "DB01"
[2]=>
string(4) "DB02"
[3]=>
string(4) "DB02"
}
Some more array-magic: make it a unique list by flipping keys and values, keys must be unique, so duplicates are killed. then flip again:
$groups = array_flip(array_flip($groups));
Result:
array(2) {
[1]=>
string(4) "DB01"
[3]=>
string(4) "DB02"
}
This is it. Write it as one line:
$groups = array_flip(array_flip(array_map("strval", $xml->xpath("//MailboxDatabase/DatabaseName"));
BTW: //
at the beginning of that xpath
statement is a wildcard
select nodes group-wise
Again xpath
, this time with a condition to select only those <MailboxDatabase>
that share the same <DatabaseName>
. Note the condition in []
:
$elements = $xml->xpath("/MailboxDatabases/MailboxDatabase[DatabaseName = '$group']");
Now iterating over $groups
:
foreach ($groups as $group) {
echo "group $group:" . PHP_EOL;
$elements = $xml->xpath("//MailboxDatabase[DatabaseName = '$group']");
foreach ($elements as $e)
echo " " . $e->MailboxServer . ": " . $e->Active . PHP_EOL;
echo PHP_EOL;
}
Result:
group DB01:
MB08: false
MB07: true
group DB02:
MB08: true
MB07: false
see it working: https://eval.in/321935