0

私は次のforループを含むPHPスクリプトを書いています:

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

$ contentは、次のようにXMLを解析したSimpleXMLElementのインスタンスです。

<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>要素が開かれ、閉じられませんでした。私の答えの残りの部分には、この開始タグが削除されているという前提条件があります。

エンドレスループは防止されません。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パス言語(XPath)バージョン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 に答える