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 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 关于大棚监测的pcb板设计
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)
  • ¥15 Vue3地图和异步函数使用
  • ¥15 C++ yoloV5改写遇到的问题