php simplexml grouping objects

后端 未结 1 1336
[愿得一人]
[愿得一人] 2020-12-20 09:11

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 i

相关标签:
1条回答
  • 2020-12-20 10:01

    Overall strategy:

    1. create a list of unique groups, that is <DatabaseName>
    2. select all <MailboxDatabase> that belong to a group and echo their <MailboxServer> and <Active>
    3. proceed to the next group and go to step 2 until you iterated over all groups.

    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

    0 讨论(0)
提交回复
热议问题