PHP - 在循环中连接具有相同属性的元素

时间:2017-04-19 09:27:55

标签: php xml foreach

我正试图" group"来自XML的元素,其中一些元素共享相同的日期,然后从这些元素中打印出某些值" groups"。

XML结构:

<parent>

    <!-- Day 1 -->
    <element date="2017-04-18D12:00:00">
        <node value="30" />
        <node value="82" /> <!-- This is the highest of the day 1 -->
        <node value="25" />
        <foo name="noon" />
    </element>
    <element date="2017-04-18D18:00:00">
        <node value="12" />
        <node value="52" />
        <node value="11" /> <!-- This is the lowest of the day 1 -->
        <foo name="evening" />
    </element>

    <!-- Day 2 -->
    <element date="2017-04-19D00:00:00">
        <node value="21" />
        <node value="78" />
        <node value="33" />
        <foo name="night" />
    </element>
    <element date="2017-04-19D06:00:00">
        <node value="35" />
        <node value="57" />
        <node value="88" />
        <foo name="morning" />
    </element>
    <element date="2017-04-19D12:00:00">
        <node value="22" />
        <node value="92" /> <!-- This is the highest of the day 2 -->
        <node value="81" /> 
        <node value="19" />
        <foo name="noon" />
    </element>
    <element date="2017-04-19D18:00:00">
        <node value="2" /> <!-- This is the lowest of the day 2 -->
        <node value="30" />
        <node value="44" />
        <foo name="evening" />
    </element>

    <!-- Day 3 -->
    <element date="2017-04-20D00:00:00">
        <node value="12" />
        <node value="99" />
        <node value="43" />
        <foo name="night" />
    </element>
    <element date="2017-04-20D06:00:00">
        <node value="65" />
        <node value="211" /> <!-- This is the highest of the day 3 -->
        <node value="16" />
        <foo name="morning" />
    </element>
    <element date="2017-04-20D12:00:00">
        <node value="32" />
        <node value="55" />
        <node value="77" /> 
        <node value="1" /> <!-- This is the lowest of the day 3 -->
        <foo name="noon" />
    </element>
    <element date="2017-04-20D18:00:00">
        <node value="68" />
        <node value="74" />
        <node value="21" />
        <foo name="evening" />
    </element>
    ...
</parent>

每个元素都有一个日期属性,我想用它来对元素进行分组。

最终结果应打印

<div class="group">
    <div>Monday</div>
    <div>11</div>
    <div>82</div>
    <div>noon</div>
    <div>evening</div>
</div>
<div class="group">
    <div>Thursday</div>
    <div>2</div>
    <div>92</div>
    <div>night</div>
    <div>morning</div>
    <div>noon</div>
    <div>evening</div>
</div>
<div class="group">
    <div>Wednesday</div>
    <div>1</div>
    <div>211</div>
    <div>night</div>
    <div>morning</div>
    <div>noon</div>
    <div>evening</div>
</div>
...

这是我到目前为止所拥有的:

$source = simplexml_load_file('http://example.com');
foreach ($source -> parent -> element as $element) {
    // Format the date value and get the day so the elements could group
    $from      = explode('D', $element['date']);
    $group_day = explode('-', trim($from[0]));

    // problem starts here :)

}

XML中的注释仅用于演示,不包含在其中。

2 个答案:

答案 0 :(得分:1)

试试这个希望它会帮助你。在这里,我使用DOMDocument检索名为element的标记,然后检索其属性date,之后您可以执行您想要的操作。

Try this code snippet here     

$source = new DOMDocument();
$source->loadXML('<parent>

    <!-- Day 1 -->
    <element date="2017-04-18D12:00:00">
        <node value="30" />
        <node value="82" /> <!-- This is the highest of the day 1 -->
        <node value="25" />
        <foo name="noon" />
    </element>
    <element date="2017-04-18D18:00:00">
        <node value="12" />
        <node value="52" />
        <node value="11" /> <!-- This is the lowest of the day 1 -->
        <foo name="evening" />
    </element>

    <!-- Day 2 -->
    <element date="2017-04-19D00:00:00">
        <node value="21" />
        <node value="78" />
        <node value="33" />
        <foo name="night" />
    </element>
    <element date="2017-04-19D06:00:00">
        <node value="35" />
        <node value="57" />
        <node value="88" />
        <foo name="morning" />
    </element>
    <element date="2017-04-19D12:00:00">
        <node value="22" />
        <node value="92" /> <!-- This is the highest of the day 2 -->
        <node value="81" /> 
        <node value="19" />
        <foo name="noon" />
    </element>
    <element date="2017-04-19D18:00:00">
        <node value="2" /> <!-- This is the lowest of the day 2 -->
        <node value="30" />
        <node value="44" />
        <foo name="evening" />
    </element>

    <!-- Day 3 -->
    <element date="2017-04-20D00:00:00">
        <node value="12" />
        <node value="99" />
        <node value="43" />
        <foo name="night" />
    </element>
    <element date="2017-04-20D06:00:00">
        <node value="65" />
        <node value="211" /> <!-- This is the highest of the day 3 -->
        <node value="16" />
        <foo name="morning" />
    </element>
    <element date="2017-04-20D12:00:00">
        <node value="32" />
        <node value="55" />
        <node value="77" /> 
        <node value="1" /> <!-- This is the lowest of the day 3 -->
        <foo name="noon" />
    </element>
    <element date="2017-04-20D18:00:00">
        <node value="68" />
        <node value="74" />
        <node value="21" />
        <foo name="evening" />
    </element>
</parent>');
$result=array();
foreach ($source->getElementsByTagName("element") as $element)
{
    $date=$element->getAttribute("date");
    $from      = explode('D', $date);
    $group_day = explode('-', trim($from[0]));
    $values=array();
    $weekDay=date("l",  strtotime($date));
    foreach($element->childNodes as $node)
    {
        if($node instanceof DOMElement)
        {
            if(!empty($node->getAttribute("value")))
            {
                $result[$group_day[2]]["values"][]=$node->getAttribute("value");
            }
            else
            {
                $result[$group_day[2]]["datetime"][]=$node->getAttribute("name");
            }
        }
    }
    $result[$group_day[2]]["weekDay"][$weekDay]=$weekDay;
}

foreach($result as $key => $value)
{
    $array=$result[$key]["values"];
    asort($array);
    $lowest=$array[key($array)];
    arsort($array);
    $highest=$array[key($array)];
    $result[$key]["values"]=array();
    $result[$key]["values"]["highest"]=$highest;
    $result[$key]["values"]["lowest"]=$lowest;
}
print_r($result);

答案 1 :(得分:1)

这是一种比last time更好的XML格式,因为它更容易关联元素。

与上次一样,让我们​​解析XML并将其放入我们可以使用的格式中。

我们将创建另一个关联地图$groups,但此时加上来自<element/>日期属性的日期。由于我们需要存储当天的时间,因此我们需要调整地图的值,以便我们可以存储<node/>值属性和<foo/>名称属性。这可以通过制作内部地图轻松完成。

$xml = simplexml_load_file('http://example.com');

// group all the value/name attributes

foreach ($xml->element as $element) {
    $datetime = (string) $element->attributes()['date'];
    // let's remove the time
    $date = substr($datetime, 0, 10);
    // check if there is a group for that date; if not create one
    if (!isset($groups[$date])) {
        $groups[$date] = [];
        // this will be used to store all the value attributes for this date
        $groups[$date]['values'] = []; 
        // this will be used to store all the name attributes for this date
        $groups[$date]['names'] = [];
    }
    // store the next value attributes in that group
    foreach ($element->node as $node) {
        $groups[$date]['values'][] = (int) $node->attributes()['value'];
    }
    // store the next name attributes in that group
    foreach ($element->foo as $foo) {
        $groups[$date]['names'][] = (string) $foo->attributes()['name'];
    }
}

// now we have everything we need to build the result

foreach ($groups as $date => $group) {
    print '<div class="group">';
    printf('<div>%s</div>', date('l', strtotime($date)));
    printf('<div>%d</div>', min($group['values']));
    printf('<div>%d</div>', max($group['values']));
    foreach ($group['names'] as $name) {
        printf('<div>%s</div>', $name);
    }
    print '</div>';
}