【问题标题】:SimpleXML - how can I list attributes of a random list of children?SimpleXML - 如何列出随机子级列表的属性?
【发布时间】:2020-08-28 02:35:59
【问题描述】:

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

我需要保留它们的顺序,然后提取 Duration 和 Power 的属性。

<?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();

如何按正确的顺序获取子项、持续时间和功率的列表?

【问题讨论】:

  • 感谢 Rob Ruchte,解决方案对我有用
  • 感谢 IMSoP,这似乎也运行良好,代码行数更少。也很高兴了解 DOM 方法,可能会派上用场。

标签: php attributes simplexml children


【解决方案1】:

这是使用DOM 代替SimpleXML 的绝佳案例。根据我的经验,除了最基本的情况外,SimpleXML 通常比 DOM 更难使用。

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

【讨论】:

  • 这里真的不需要DOM; OP 已经有 foreach 循环工作,只需要他们的 $node 变量的属性。
【解决方案2】:

我觉得你想多了。您有一个表示 XML 节点的变量,并且需要该节点的属性。就这么简单:

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

(如果你正在处理命名空间,或者如果你想遍历一个节点的所有属性,你只需要显式调用-&gt;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

【讨论】:

    猜你喜欢
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 2011-12-06
    • 2014-06-12
    • 1970-01-01
    • 2013-08-14
    • 1970-01-01
    • 2014-12-03
    相关资源
    最近更新 更多