php simplexml分组对象

时间:2015-04-30 19:45:51

标签: php xml group-by simplexml

在开始之前,我想说我是一个将XML读入PHP的菜鸟,但到目前为止我已经设法加载XML并将数据显示在PHP页面上。 我的下一个测试是分组项目。

这是一个XML代码段:

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

如您所见,&#34; DatabaseName&#34;两个项目是相同的但是&#34; Active&#34;是不同的。 我想要做的是在php中显示上面的xml

DB01 - MB08 - false | DB01 - MB07 - 是

DB02 - MB08 - true | DB01 - MB07 - 错误

使用以下元素 (数据库) - (邮箱服务器) - (主动)| ...

请有人帮我一把,请尝试解释一下代码。

1 个答案:

答案 0 :(得分:0)

总体战略:

  1. 创建一个唯一群组列表,即<DatabaseName>
  2. 选择属于某个论坛的所有<MailboxDatabase>,并回复他们的<MailboxServer><Active>
  3. 进入下一组并转到第2步,直到您遍历所有组。
  4. 现在是时候学习从XML中选择某些节点了,最好用xpath来完成。简而言之,xpath用于XML,SQL用于数据库。

    假设您准备好SimpleXML个对象:

    $xml = simplexml_load_string($x); // assume XML in $x
    

    创建唯一群组列表

    获取数组中的所有<DatabaseName>

    $groups = $xml->xpath("/MailboxDatabases/MailboxDatabase/DatabaseName");
    

    $groups现在包含一个SimpleXML元素数组,所以让我们做一些array-magic来将它们转换为字符串:

    $groups = array_map("strval", $groups);
    

    结果(var_dump):

    array(4) {
      [0]=>
      string(4) "DB01"
      [1]=>
      string(4) "DB01"
      [2]=>
      string(4) "DB02"
      [3]=>
      string(4) "DB02"
    }
    

    更多阵列魔术:通过翻转键和值使其成为唯一列表,键必须是唯一的,因此重复会被杀死。然后再翻转:

    $groups = array_flip(array_flip($groups));
    

    结果:

    array(2) {
      [1]=>
      string(4) "DB01"
      [3]=>
      string(4) "DB02"
    }
    

    就是这样。把它写成一行:

    $groups = array_flip(array_flip(array_map("strval", $xml->xpath("//MailboxDatabase/DatabaseName"));
    

    BTW://语句开头的xpath是通配符

    按组分组选择

    再次xpath,这次条件只选择那些共享相同<MailboxDatabase>的{​​{1}}。请注意<DatabaseName>中的条件:

    []

    现在迭代$elements = $xml->xpath("/MailboxDatabases/MailboxDatabase[DatabaseName = '$group']");

    $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;
    } 
    

    看到它有效:https://eval.in/321935