0

我正在编写一个 PHP 脚本,其中包含以下for循环:

for($x=count($content->data->parameters[0]->weather->children());$content->data->weather->{"weather-conditions"}[$x]['weather-type']==NULL;--$x){
    echo $x."\n";
}

其中 $content 是 SimpleXMLElement 的一个实例,它解析 XML 如下:

<dwml xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:noNamespaceSchemaLocation="http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd">
<data>
<parameters applicable-location="point1">
<location>
<weather time-layout="k-p3h-n41-3">
<name>Weather Type, Coverage, and Intensity</name>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="likely" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="moderate" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="moderate" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="moderate" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="moderate" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow showers" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow showers" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow showers" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow showers" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="slight chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="slight chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
</weather>
</parameters>
</data>
</dwml>

编辑:解析此文件后,这就是var_dump($content->data->parameters[0]->weather);产生的结果:

object(SimpleXMLElement)#4 (3) {
  ["@attributes"]=>
  array(1) {
    ["time-layout"]=>
    string(11) "k-p3h-n41-3"
  }
  ["name"]=>
  string(37) "Weather Type, Coverage, and Intensity"
  ["weather-conditions"]=>
  array(41) {
    [0]=>
    object(SimpleXMLElement)#2 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(13) "slight chance"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [1]=>
    object(SimpleXMLElement)#5 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(13) "slight chance"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [2]=>
    object(SimpleXMLElement)#6 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(6) "chance"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [3]=>
    object(SimpleXMLElement)#7 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(6) "likely"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [4]=>
    object(SimpleXMLElement)#8 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(10) "definitely"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [5]=>
    object(SimpleXMLElement)#9 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(10) "definitely"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [6]=>
    object(SimpleXMLElement)#10 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(10) "definitely"
            ["intensity"]=>
            string(8) "moderate"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(5) "areas"
            ["intensity"]=>
            string(4) "none"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(12) "blowing snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
    [7]=>
    object(SimpleXMLElement)#11 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(10) "definitely"
            ["intensity"]=>
            string(8) "moderate"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(5) "areas"
            ["intensity"]=>
            string(4) "none"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(12) "blowing snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
    [8]=>
    object(SimpleXMLElement)#12 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(10) "definitely"
            ["intensity"]=>
            string(8) "moderate"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(5) "areas"
            ["intensity"]=>
            string(4) "none"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(12) "blowing snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
    [9]=>
    object(SimpleXMLElement)#13 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(10) "definitely"
            ["intensity"]=>
            string(8) "moderate"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(5) "areas"
            ["intensity"]=>
            string(4) "none"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(12) "blowing snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
    [10]=>
    object(SimpleXMLElement)#14 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(6) "chance"
            ["intensity"]=>
            string(5) "light"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(5) "areas"
            ["intensity"]=>
            string(4) "none"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(12) "blowing snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
...//More in here, trivial.
    [40]=>
    object(SimpleXMLElement)#44 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(6) "chance"
            ["intensity"]=>
            string(5) "light"
            ["weather-type"]=>
            string(4) "rain"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(6) "chance"
            ["intensity"]=>
            string(5) "light"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
  }
}

由于最后的元素有时会是空的,我想要最新的非空天气项目,我将 x 设置为天气数组中最后一个项目的索引,并尝试向后工作,但页面没有加载,并且错误日志中没有任何内容。编辑:我已将方法更改为此,以使其更易于理解:

for($x=0; $content->data->parameters[0]->weather->{"weather-conditions"}[count($content->data->parameters[0]->weather->children())-$x]['weather-type']==NULL; $x++){
    echo $x."\n";
}

编辑:如果不清楚,我需要通过子数组向后递归,而不是向前。

4

2 回答 2

1

我可以在您的问题中找到一些不同的问题:

XML 无效。请在提问时提供工作数据,此处<location>元素已打开且从未关闭。我的其余答案的前提条件是 this start-tag has been removed

没有阻止无限循环。低于 0是没有意义的,$x但你不检查它。您应该添加这样的检查,这样您就不会仅仅因为您在中断决策逻辑的另一部分犯了一些错误而创建了一个无限循环:

for (
    $x = count($content->data->parameters[0]->weather->children());
    $x >= 0 && $content->data->weather->{"weather-conditions"}[$x]['weather-type'] == NULL;
    --$x
) {
    echo $x . "\n";
}

使用(固定的)示例数据,现在将从 42 计数到 0,但不低于 0。至少无限循环已被删除。清除这些技术问题后,您可以专注于问题域:

由于最后的元素有时会为空,我想要最新的非空天气项目

好吧,您的实际示例 XML 不包含任何<weather>元素(即<weather>没有任何子元素的元素。所以不清楚您在问什么。

但是,它包含空 <weather-conditions/>元素,因此作为其余答案的先决条件,我取而代之。

XML 没有特定的顺序 - 至少不是设计使然 - 正如您的示例 XML 所示,空<weather-conditions/>元素更多地位于文档的中间而不是末尾。您真正想要的是所有 <weather-conditions>包含子元素的元素(此处<value>)。您最好使用 xpath 查询来做到这一点。

因此,您首先查询所有具有 <value>子元素的元素,然后获取最后一个元素(按文档顺序)。所以我们开始:

list($lastCondition) = $content->xpath('
    (
        /*/data/parameters/weather/weather-conditions[value]
    )[position() = last()]
');

然后该变量$lastCondition包含最后一个非空元素,这里是基于您的示例 XML 的 XML 输出:

<weather-conditions>
                    <value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
                        <visibility xsi:nil="true"/>
                    </value>
                    <value coverage="chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
                        <visibility xsi:nil="true"/>
                    </value>
                </weather-conditions>

如您所见,您的问题有很多不清楚的地方,这使得回答变得更加困难。最后,我希望这仍然有帮助。

使用的方法是SimpleXMLElement::xpath(),Xpath 1.0(由该方法使用)在 W3C 站点XML Path Language (XPath) Version 1.0上指定,Stackoverflow 本身包含很多示例,所以最好先在这里搜索。

于 2013-03-05T09:15:15.557 回答
0

事实证明,我在层次结构中跳过了几个级别,这就是为什么检查字符串是否为 NULL 的条件总是返回 TRUE(因此是无限循环)。最终代码:

for($x=count($content->data->parameters[0]->weather->children()); $x>0; $x--){
    if($content->data->parameters[0]->weather->{"weather-conditions"}[$x]!=NULL){
        return $content->data->parameters[0]->weather->{"weather-conditions"}[$x][0]->value['weather-type'];
    }
}
于 2013-03-05T00:20:18.690 回答