dthy81285 2016-12-07 02:30
浏览 36
已采纳

访问XML数据的PHP foreach语句问题

First, I am pretty clueless with PHP, so be kind! I am working on a site for an SPCA (I'm a Vet and a part time geek). The PHP accesses an xml file from a portal used to administer the shelter and store images, info. The file writes that xml data to JSON and then I use the JSON data in a handlebars template, etc. I am having a problem getting some data from the xml file to outprint to JSON.

The xml file is like this:

 </DataFeedAnimal>    
<AdditionalPhotoUrls>
<string>doc_73737.jpg</string>
 <string>doc_74483.jpg</string>
 <string>doc_74484.jpg</string>
 </AdditionalPhotoUrls>
 <PrimaryPhotoUrl>19427.jpg</PrimaryPhotoUrl>
 <Sex>Male</Sex>
 <Type>Cat</Type>
 <YouTubeVideoUrls>
 <string>http://www.youtube.com/watch?v=6EMT2s4n6Xc</string>    
 </YouTubeVideoUrls>
 </DataFeedAnimal>

In the PHP file, written by a friend, the code is below, (just part of it), to access that XML data and write it to JSON:

<?php

  $url = "http://eastbayspcapets.shelterbuddy.com/DataFeeds/AnimalsForAdoption.aspx";
if ($_GET["type"] == "found") {
$url = "http://eastbayspcapets.shelterbuddy.com/DataFeeds/foundanimals.aspx";
} else if ($_GET["type"] == "lost") {
$url = "http://eastbayspcapets.shelterbuddy.com/DataFeeds/lostanimals.aspx";
 }

$response_xml_data = file_get_contents($url);
$xml = simplexml_load_string($response_xml_data);
$data = array();

 foreach($xml->DataFeedAnimal as $animal)
{
$item = array();
$item['sex'] = (string)$animal->Sex;
$item['photo'] = (string)$animal->PrimaryPhotoUrl;
$item['videos'][] = (string)$animal->YouTubeVideoUrls;
$item['photos'][] = (string)$animal->PrimaryPhotoUrl;
foreach($animal->AdditionalPhotoUrls->string as $photo) {
        $item['photos'][] = (string)$photo;
    }

$item['videos'] = array();
$data[] = $item;
}

echo file_put_contents('../adopt.json', json_encode($data));
echo json_encode($data);
?>

The JSON output works well but I am unable to get 'videos' to write out to the JSON file as the 'photos' do. I just get '/n'!

Since the friend who helped with this is no longer around, I am stuck. I have tried similar code to the foreach statement for photos but am getting nowhere. Any help would be appreciated and the pets would appreciate it as well!

  • 写回答

2条回答 默认 最新

  • douruyun8153 2016-12-07 03:07
    关注

    The trick with such implementations is to always look what you have got by dumping data structures to a log file or command line. Then to take a look at the documentation of the data you see. That way you know exactly what data you are working with and how to work with it ;-)

    Here it turns out that the video URLs you are interested in are placed inside an object of type SimpleXMLElement with public properties, which is not really surprising if you look at the xml structure. The documentation of class SimpleXMLElement shows the method children() which iterates through all children. Just what we are looking for...

    That means a clean implementation to access those sets should go along these lines:

    foreach($animal->AdditionalPhotoUrls->children() as $photo) {
      $item['photos'][] = (string)$photo;
    }
    foreach($animal->YouTubeVideoUrls->children() as $video) {
      $item['videos'][] = (string)$video;
    }
    

    Take a look at this full and working example:

    <?php
    $response_xml_data = <<< EOT
    <DataFeedAnimal>
      <AdditionalPhotoUrls>
        <string>doc_73737.jpg</string>
        <string>doc_74483.jpg</string>
        <string>doc_74484.jpg</string>
      </AdditionalPhotoUrls>
      <PrimaryPhotoUrl>19427.jpg</PrimaryPhotoUrl>
      <Sex>Male</Sex>
      <Type>Cat</Type>
      <YouTubeVideoUrls>
        <string>http://www.youtube.com/watch?v=6EMT2s4n6Xc</string>
        <string>http://www.youtube.com/watch?v=hgfg83mKFnd</string>
      </YouTubeVideoUrls>
    </DataFeedAnimal>
    EOT;
    
    $animal = simplexml_load_string($response_xml_data);
    
    $item = [];
    $item['sex'] = (string)$animal->Sex;
    $item['photo'] = (string)$animal->PrimaryPhotoUrl;
    $item['photos'][] = (string)$animal->PrimaryPhotoUrl;
    foreach($animal->AdditionalPhotoUrls->children() as $photo) {
      $item['photos'][] = (string)$photo;
    }
    $item['videos'] = [];
    foreach($animal->YouTubeVideoUrls->children() as $video) {
      $item['videos'][] = (string)$video;
    }
    
    echo json_encode($item);
    

    The obvious output of this is:

    {
      "sex":"Male",
      "photo":"19427.jpg",
      "photos" ["19427.jpg","doc_73737.jpg","doc_74483.jpg","doc_74484.jpg"],
      "videos":["http:\/\/www.youtube.com\/watch?v=6EMT2s4n6Xc","http:\/\/www.youtube.com\/watch?v=hgfg83mKFnd"]
    }
    

    I would however like to add a short hint:

    In m eyes it is questionable to convert such structured information into an associative array. Why? Why not a simple json_encode($animal)? The structure is perfectly fine and should be easy to work with! The output of that would be:

    {
      "AdditionalPhotoUrls":{
        "string":[
          "doc_73737.jpg",
          "doc_74483.jpg",
          "doc_74484.jpg"
        ]
      },
      "PrimaryPhotoUrl":"19427.jpg",
      "Sex":"Male",
      "Type":"Cat",
      "YouTubeVideoUrls":{
        "string":[
          "http:\/\/www.youtube.com\/watch?v=6EMT2s4n6Xc",
          "http:\/\/www.youtube.com\/watch?v=hgfg83mKFnd"
        ]
      }
    }
    

    That structure describes objects (items with an inner structure, enclosed in json by {...}), not just arbitrary arrays (sets without a structure, enclosed in json by a [...]). Arrays are only used for the two unstructured sets of strings in there: photos and videos. This is much more logical, once you think about it...

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分