dongxuan8227 2015-04-30 19:45
浏览 23
已采纳

php simplexml分组对象

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.

  • 写回答

1条回答 默认 最新

  • dtvhqlc57127 2015-05-01 00:19
    关注

    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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 2024-五一综合模拟赛
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭