1

XMLの属性にアクセスするのに問題があります。私のコードは以下の通りです。最初は2つのループがあり、これは問題なく機能していました。

最初に画像名を取得し、次に2番目のループを使用してストーリーの見出しとストーリーの詳細を取得します。次に、すべてをデータベースに挿入します。コードを整理して、ループを1つだけ使用したいと思います。私の画像名はHref属性に保存されています。()

サンプルXMLレイアウト(http://pastie.org/1850682)。XMLレイアウトは少し面倒なので、2つのループを使用する理由がありました。

$xml = new SimpleXMLElement('entertainment/Showbiz.xml', null, true);

    // Get story images
    //$i=0;
    //$image = $xml->xpath('NewsItem/NewsComponent/NewsComponent/NewsComponent/NewsComponent/NewsComponent/ContentItem');
  //  foreach($image as $imageNode){
    //  $attributeArray = $imageNode->attributes(); 
    //  if ($attributeArray != ""){
    //      $imageArray[$i] = $attributeArray;
    //      $i++;
    //  }
    //}

// Get story header & detail
$i=0;
$story = $xml->xpath('NewsItem/NewsComponent/NewsComponent/NewsComponent');
foreach($story as $contentItem){
    //$dbImage = $imageArray[$i]['Href'];
    foreach($contentItem->xpath('ContentItem/DataContent/nitf/body/body.head/hedline/hl1') as $headline){
        $strDetail = "";
        foreach($contentItem->xpath('ContentItem/DataContent/nitf/body/body.content/p') as $detail){
            $strDetail .= '<p>'.$detail.'</p>';
            foreach($contentItem->xpath('NewsComponent/NewsComponent/ContentItem') as $imageNode){
                $dbImage = $imageNode->attributes();    
            }
        }

        $link = getUnique($headline);

        $sql = "INSERT INTO tablename (headline, detail, image, link) VALUES ('".mysql_real_escape_string($headline)."', '".mysql_real_escape_string($strDetail)."', '".mysql_real_escape_string($dbImage)."', '".$link."')";
        if (mysql_query($sql, $db) or die(mysql_error())){
            echo "Loaded ";
        }else{
            echo "Not Loaded "; 
        }

    }
    $i++;
}

私はそれを手に入れようと思っています。4番目のネストされたforeachループにいくつかのechoステートメントを入れてみましたが、何も出ていませんでした。したがって、そのループは実行されません。私はこれに数時間いて、グーグルもしました、ただそれを得ることができません。

他のすべてが失敗した場合は、2つのループの使用に戻ります。

よろしく、スティーブン

4

1 に答える 1

2

これを追跡するのはかなり困難でした。構造を単純化して、関心のある階層の部分を確認できるようにしました。

簡略化されたXML階層

Duid属性を持つNewsComponentは、 1つの完全なニュースを定義/含むもののようです。2つの子のうち、最初の子NewsComponentには要約とテキストが含まれ、2番目の子NewsComponentには画像が含まれます。

最初のXPathクエリは'NewsItem/NewsComponent/NewsComponent/NewsComponent'、最初のNewsComponentの子(本文テキストを持つ子)に対するものです。画像がそのNewsComponent内にないため、その時点から画像を見つけることができません。あなたは1レベル深くなりすぎました。(PHP通知を受け取ったという事実に気づきました:未定義の変数:dbImage。)したがって、最初のXPathクエリをレベルに戻し、必要に応じてその余分なレベルを後続のXPathクエリに追加します。

これから:

$story = $xml->xpath('NewsItem/NewsComponent/NewsComponent/NewsComponent');
foreach($story as $contentItem){
  foreach($contentItem->xpath('ContentItem/DataContent/nitf/body/body.head/hedline/hl1') as $headline){
    foreach($contentItem->xpath('ContentItem/DataContent/nitf/body/body.content/p') as $detail){
      foreach($contentItem->xpath('NewsComponent/NewsComponent/ContentItem') as $imageNode){ /* ... */ }}}}

これに:

$story = $xml->xpath('NewsItem/NewsComponent/NewsComponent');
foreach($story as $contentItem){
  foreach($contentItem->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.head/hedline/hl1') as $headline){
    foreach($contentItem->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.content/p') as $detail){
      foreach($contentItem->xpath('NewsComponent/NewsComponent/NewsComponent/ContentItem') as $imageNode){ /* ... */ }}}}

ただし、それ以降も画像は機能しません。ループを使用しているため(場合によっては不必要に)、$dbImage空の文字列に再割り当てされます。最初のContentItemにはHref属性があり、これはに割り当てられ$dbImageます。ただし、次のContentItemにループします。このコンテンツには属性がないため$dbImage、空の値で上書きされます。次のように、 Href属性を持つContentItemのみを検索するようにXPathクエリを変更することをお勧めします。

->xpath('NewsComponent/NewsComponent/NewsComponent/ContentItem[@Href]')

それはそれをする必要があります。


他の考え

可能であれば、このコードをクリーンアップするためにリファクタリングします。

先に述べたように、必要のないときにループしてネストしていることがあり、それを追跡するのが難しくなり、論理的なバグ(画像のような)が発生する可能性があります。このファイルの構造は常に一貫しているようです。もしそうなら、あなたはいくつかのループをやめて、あなたが探しているデータの断片をまっすぐに行くことができます。あなたはこのようなことをすることができます:

// Get story header & detail
$stories = $xml->xpath('/NewsML/NewsItem/NewsComponent/NewsComponent');
foreach ($stories as $story) {
    $headlineItem = $story->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.head/hedline/hl1');
    $headline = $headlineItem[0];

    $detailItems = $story->xpath('NewsComponent/ContentItem/DataContent/nitf/body/body.content/p');
    $strDetail = '<p>' . implode('</p><p>', $detailItems) . '</p>';

    $imageItem = $story->xpath('NewsComponent/NewsComponent/NewsComponent/ContentItem[@Href]');
    $imageAtts = $imageItem[0]->attributes();
    $dbImage = $imageAtts['Href'];

    $link = getUnique($headline);

    $sql = "INSERT INTO tablename (headline, detail, image, link) VALUES ('".mysql_real_escape_string($headline)."', '".mysql_real_escape_string($strDetail)."', '".mysql_real_escape_string($dbImage)."', '".$link."')";
    if (mysql_query($sql, $db) or die(mysql_error())) {
        echo "Loaded ";
    } else {
        echo "Not Loaded "; 
    }
}
于 2011-04-30T22:13:01.313 に答える