SimpleXML-如何列出子级随机列表的属性?

问题描述

我有一些带有多个子级的xml。它们的名称已知,数量和顺序未知。 在这种情况下,它们可以是FreeRide或SteadyState。

我需要保留其顺序,然后提取“持续时间”和“力量”的属性。

<?php
$xml='<workout_file>
    <workout>
       <FreeRide Duration="300" Power="1.3"/>
        <SteadyState Duration="300" Power="0.55"/>
        <FreeRide Duration="10"  Power="1.2"/>
        <SteadyState Duration="180" Power="0.55"/>
        <FreeRide Duration="10"  Power="1.1"/>
        <SteadyState Duration="120" Power="0.55"/>
    </workout>
</workout_file>';

$xml=simplexml_load_string($xml);

$count = 0;
foreach($xml->workout->children() as $node ){
    $type = $node->getName();
    echo $type." position: ".$count."<br>";
    $count++;

    //Get Attributes
    //$attr =  $xml->workout->$$type[$count]->attributes(); //Doesn't work Undefined variable: FreeRide
    //echo "Duration: ".$attr['Duration']."<br>";
    //echo "Power: ".$attr['Power']."<br>";
}

我可以使用此代码列出孩子以及他们的位置。 但是我不确定如何获取属性,因为确切的子名称不知道(它们可以按任何顺序排列)。

注意:这里仅列出FreeRide子级: $ attr = $ xml-> workout-> FreeRide [$ count]-> attributes();

我如何以正确的顺序获得孩子的名单,持续时间和力量?

解决方法

使用DOM代替SimpleXML是一个很好的例子。根据我的经验,在除最基本的情况以外的所有情况下,与XML相比,SimpleXML通常更难使用。

<?php
$xml='<workout_file>
    <workout>
       <FreeRide Duration="300" Power="1.3"/>
        <SteadyState Duration="300" Power="0.55"/>
        <FreeRide Duration="10"  Power="1.2"/>
        <SteadyState Duration="180" Power="0.55"/>
        <FreeRide Duration="10"  Power="1.1"/>
        <SteadyState Duration="120" Power="0.55"/>
    </workout>
</workout_file>';

//Instantiate a DOMDocument and load our XML
$doc = new DOMDocument();
$doc->loadXML($xml);

// Instantiate DOMXpath with our document
$xpath = new DOMXPath($doc);

//Get all of our workout elements and iterate through them
$workoutElements = $xpath->query('/workout_file/workout');
foreach($workoutElements as $currElement)
{
    //Iterate through the children
    $count = 0;
    foreach($currElement->childNodes as $currIntervalNode)
    {
        /*
         * Since we're going through ALL of the children,some of them will be whitespace nodes we don't care about,* so only look at nodes with attributes
         */
        if($currIntervalNode->hasAttributes())
        {
            // the nodeName attribute is the tag name
            $type = $currIntervalNode->nodeName;

            // Pull out the attribute vaules by name
            $duration = $currIntervalNode->getAttribute('Duration');
            $power = $currIntervalNode->getAttribute('Power');

            echo 'Position: '.$count++.'<br>'.PHP_EOL;
            echo 'Type: '.$type.'<br>'.PHP_EOL;
            echo 'Duration: '.$duration.'<br>'.PHP_EOL;
            echo 'Power: '.$power.'<br>'.PHP_EOL;
        }
    }
}
,

我认为您对此考虑过多。您有一个表示XML节点的变量,并且需要该节点的属性。就是这么简单:

//Get Attributes
echo "Duration: ".$node['Duration']."<br>";
echo "Power: ".$node['Power']."<br>";

(如果您要处理名称空间,或者要遍历节点的所有属性,则在这种情况下都不适用),只需显式调用->attributes()

总共:

<?php
$xml='<workout_file>
    <workout>
       <FreeRide Duration="300" Power="1.3"/>
        <SteadyState Duration="300" Power="0.55"/>
        <FreeRide Duration="10"  Power="1.2"/>
        <SteadyState Duration="180" Power="0.55"/>
        <FreeRide Duration="10"  Power="1.1"/>
        <SteadyState Duration="120" Power="0.55"/>
    </workout>
</workout_file>';

$xml=simplexml_load_string($xml);

$count = 0;
foreach($xml->workout->children() as $node ){
    $type = $node->getName();
    echo $type." position: ".$count."<br>";
    $count++;

    //Get Attributes
    echo "Duration: ".$node['Duration']."<br>";
    echo "Power: ".$node['Power']."<br>";
}

Live demo

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...