2011-04-25 61 views
3

這裏是我的物體看起來像print_r的(這是由PHP SDK爲亞馬遜Web服務的簡單數據庫返回的對象。循環訪問的SimpleXML Objext PHP

[GetAttributesResult] => CFSimpleXML Object 
      (
       [Attribute] => Array 
        (
         [0] => CFSimpleXML Object 
          (
           [Name] => data_datein 
           [Value] => 2011-04-23 
          ) 

         [1] => CFSimpleXML Object 
          (
           [Name] => data_estatus 
           [Value] => 0 
          ) 

         [2] => CFSimpleXML Object 
          (
           [Name] => data_status 
           [Value] => 1 
          ) 

         [3] => CFSimpleXML Object 
          (
           [Name] => data_title 
           [Value] => Company Info 
          ) 

         [4] => CFSimpleXML Object 
          (
           [Name] => data_tags 
           [Value] => firsttag 
          ) 

         [5] => CFSimpleXML Object 
          (
           [Name] => data_tags 
           [Value] => secondtag 
          ) 

         [6] => CFSimpleXML Object 
          (
           [Name] => data_tags 
           [Value] => thirdtag 
          ) 

         [7] => CFSimpleXML Object 
          (
           [Name] => data_files 
           [Value] => company_info.flv 
          ) 

         [8] => CFSimpleXML Object 
          (
           [Name] => data_id 
           [Value] => 8993 
          ) 

        ) 

      ) 

我有一個功能,在迭代GetAttributesResult對象並創建一個關聯數組,使得通過名稱引用我的字段變得很容易,我的一個名字是data_tags,它重複了未知次數,我想返回data_tags作爲這些值的簡單索引數組。這是我的功能,不起作用。

function attrToArray($select) { 
$results = array(); 
$x = 0; 
foreach($select->body->GetAttributesResult as $result) { 
    foreach ($result as $field) { 
     if (array_key_exists($field,$results[$x])) { 
      $results[$x][ (string) $field->Name ][] = (string) $field->Value; 
     } else { 
      $results[$x][ (string) $field->Name ] = (string) $field->Value; 
     } 
    } 
    $x++; 
} 
return $results; 
} 

我不知道這是否是最優雅的解決方案,但我不明白爲什麼它不起作用。 array_key_exists不返回true。由於錯誤,我能夠測試in_array($field-Name,$results[$x]),並構建了我重複的$ field-> Name值的數組......但它也將所有其他值轉換爲單個項目嵌套數組...因此它似乎返回真的比我想象的還要多。儘管那裏的連字符是我錯誤地使用的 - >哪個不會返回true,所以我對那裏發生的事情感到困惑。這是print_r來顯示返回的內容。

Array ([0] => Array ( 
[data_datein] => 2011-04-23 
[data_estatus] => 0 
[data_status] => Array ([0] => 1) 
[data_title] => Array ([0] => Company Info) 
[data_tags] => Array ( 
    [0] => firsttag 
    [1] => secondtag 
    [2] => thirdtag) 
[data_files] => Array ([0] => company_info.flv) 
[data_id] => Array ([0] => 8993))) 

上我可能會如何處理這更好的...而且最起碼,如果有人可以找出任何指針,建議或指導我怎樣才能到上述陣列而對其他非冗餘的嵌套數組領域。非常感謝!

這裏是$resultprint_r() CFSimpleXML對象 ( [屬性] =>數組 ( [0] => CFSimpleXML對象 ( [名稱] => data_datein [數值] => 2011-04 -23 )

 [1] => CFSimpleXML Object 
      (
       [Name] => data_estatus 
       [Value] => 0 
      ) 

     [2] => CFSimpleXML Object 
      (
       [Name] => data_title 
       [Value] => 0001 01 Company Name 
      ) 

     [3] => CFSimpleXML Object 
      (
       [Name] => data_status 
       [Value] => 1 
      ) 

     [4] => CFSimpleXML Object 
      (
       [Name] => data_tags 
       [Value] => good stuff 
      ) 

     [5] => CFSimpleXML Object 
      (
       [Name] => data_tags 
       [Value] => save tags 
      ) 

     [6] => CFSimpleXML Object 
      (
       [Name] => data_tags 
       [Value] => tagger works 
      ) 

     [7] => CFSimpleXML Object 
      (
       [Name] => data_files 
       [Value] => 0001_01_company_name.flv 
      ) 

     [8] => CFSimpleXML Object 
      (
       [Name] => data_id 
       [Value] => yFKwIxjIhH 
      ) 

    ) 

) 

和這裏是$field(迭代和由<hr>標籤分離的print_r()。)

CFSimpleXML Object 
    (
     [Name] => data_datein 
     [Value] => 2011-04-23 
) 
    <hr>CFSimpleXML Object 
    (
     [Name] => data_estatus 
     [Value] => 0 
) 
    <hr>CFSimpleXML Object 
    (
     [Name] => data_title 
     [Value] => 0001 01 Company Name 
) 
    <hr>CFSimpleXML Object 
    (
     [Name] => data_status 
     [Value] => 1 
) 
    <hr>CFSimpleXML Object 
    (
     [Name] => data_tags 
     [Value] => good stuff 
) 
    <hr>CFSimpleXML Object 
    (
     [Name] => data_tags 
     [Value] => save tags 
) 
    <hr>CFSimpleXML Object 
    (
     [Name] => data_tags 
     [Value] => tagger works 
) 
    <hr>CFSimpleXML Object 
    (
     [Name] => data_files 
     [Value] => 0001_01_company_name.flv 
) 
    <hr>CFSimpleXML Object 
    (
     [Name] => data_id 
     [Value] => yFKwIxjIhH 
) 
+0

我喜歡simplexml!這是最好的=) – Rudie 2011-04-25 12:52:52

+0

你可以添加$ result和$ field的print_r嗎? – Eugene 2011-04-25 12:56:59

回答

-1
function attrToArray($select) { 
$results = array(); 
$x = 0; 
foreach ($select->body->GetAttributesResult as $result) { 
    foreach ($result as $field) { 
     $check = (string) $field->Name; 
     if (isset($field) && array_key_exists($check, $results[$x])) { 
      if (! is_array($results[ $x ][$check])) { 
       $val = (string) $results[ $x ][$check]; 
       $results[ $x ][ $check ] = array(); 
       $results[ $x ][ $check ][] = $val; 
      } 
     $results[ $x ][ $check ][] = (string) $field->Value; 
     } else { 
      $results[ $x ][ $check ] = (string) $field->Value; 
     } 
    } 
    $x++; 
} 
return $results; 
} 
+0

如果在轉換期間會發生什麼'check'將是一個空字符串,'field'沒有設置。它可能會觸發非法抵消。 – Eugene 2011-04-28 05:34:54

0

enter code here你的意思是這樣的:

$data_tags = array(); 
foreach ($select->body->GetAttributesResult AS $attr) { 
    if ($attr->Name == 'data_tags') { 
    $data_tags[] = $attr->Value; 
    } 
} 

否則,我不知道你想要什麼=)

編輯
確定GetAttributesResult是正確的?你的意思是http://www.php.net/manual/en/simplexmlelement.attributes.php

+0

GetAttributesResult是我使用的SDK返回的對象的名稱。除非必須,否則我不想將'data_tags'硬編碼到邏輯中。任何多餘的名稱 - 我想轉換爲一個數組。 – Ecropolis 2011-04-25 14:00:59

0

我會建議這樣的事情。

更新:

function getAttributesIntoArray($select) 
{ 
    $results = array(); 
    $x  = 0; 

    foreach ($select->body->GetAttributesResult as $result) 
    { 
     foreach ($result as $field) 
     { 
      if (! isset($results[ $x ])) 
      { 
       $results[ $x ] = array(); 
      } 

      // Assuming, that if the $field->Value is array, then it probably have only one element 
      if ($field) 
      { 
       // or if (isset($results[ $x ][ (string) $field->Name ])) instead of array_key_exists 
       if (array_key_exists((string) $field->Name, $results[ $x ])) 
       { 
        $results[ $x ][ (string) $field->Name ][] = (is_array($field->Value)) ? $field->Value[0] : $field->Value; 
       } 
       else 
       { 
        $results[ $x ][ (string) $field->Name ] = (is_array($field->Value)) ? $field->Value[0] : $field->Value; 
       } 
      } 
     } 

     $x++; 
    } 

    return $results; 
} 
+0

謝謝。看起來應該可以工作......但我只能得到最後一個tag_name,並且該值沒有被轉換爲數組,因此array_key_exits一定不能評估爲true。 – Ecropolis 2011-04-25 14:36:43

+0

你可以像我以前問過的那樣添加'$ result'和'$ field'的'print_r()'並將它們添加到你的主文章中?該會有更好的理解,我可以建議一些,這是有效的。 – Eugene 2011-04-25 14:46:40

+0

謝謝。我最近的嘗試是這樣的。我想也許檢查值is_array,如果它不是保存它的價值;轉換它,存儲它....有道理..? array_key_exists似乎失敗。 '如果($ &&場array_key_exists($現場>名稱,$結果[$ X])) \t \t \t { \t \t \t \t如果(!is_array($結果[$ X] [$現場>名稱] )) \t \t \t \t { \t \t \t \t $ VAL = $結果[$ X] [$現場>名]; \t \t \t \t $ results [$ x] = array($ field-> Name = $ val); \t \t \t \t} \t \t \t \t $結果[$ X] [(字符串)$現場>名] [] =(字符串)$現場>值; \t \t \t \t // return'true'; \t \t \t}' – Ecropolis 2011-04-25 17:48:13

8

在AWS PHP SDK,您可以使用to_json()to_stdClass()甚至to_array()從CFSimpleXML對象找回其他數據類型。對於SimpleXML對象,類型轉換也很重要!

PHP有一個叫做ArrayObject的對象,它或多或少是一個數組的OOP版本。當你調用CFSimpleXML-> to_array()時,你會得到一個CFArray對象,該對象封裝了具有額外功能的本地ArrayObject對象。

$array = $response->body->GetAttributesResult->to_array(); 
list($name, $value) = $array['Attribute']->first()->map(function($node, $i) { 
    return (string) $node; 
}); 

http://docs.amazonwebservices.com/AWSSDKforPHP/latest/#i=CFSimpleXML http://docs.amazonwebservices.com/AWSSDKforPHP/latest/#i=CFArray

+0

如果to_json等工作類似json_encode,我有點懷疑它實際上一直會給XML的JSON表示。在保留屬性的同時這樣做總是會非常醜陋或不一致。 – Brian 2012-08-17 09:04:38

0

我能得到這個工作。希望這可以幫助。

protected function CFResponseToArray($response) 
    { 
     try { 
      if ($response->isOK()) { 
      $responseObj = $response->body->to_array()->getArrayCopy(); 
      //log_message('info', print_r($responseObj, true)); 
      $result = array(); 
      if (isset($responseObj['SelectResult']['Item'])) { 
       if (is_array($responseObj['SelectResult']['Item'])) { 
        if (isset($responseObj['SelectResult']['Item']['Name'])) { 
         $itemObj = array(); 
         //log_message('info', print_r($responseObj['SelectResult'], true)); 
         $resultItem = $responseObj['SelectResult']['Item']; 
         $itemObj['Id'] = $resultItem['Name']; 
         $attributes = $resultItem['Attribute']; 
         for ($i = 0; $i < count($attributes); $i++) { 
          $itemObj[$attributes[$i]['Name']] = $attributes[$i]['Value']; 
         } 
         $result[] = $itemObj; 
        } else { 
         //log_message('info', print_r($responseObj['SelectResult'], true)); 
         foreach ($responseObj['SelectResult']['Item'] as $resultItem) { 

          $itemObj = array(); 
          $itemObj['Id'] = $resultItem['Name']; 
          $attributes = $resultItem['Attribute']; 
          for ($i = 0; $i < count($attributes); $i++) { 
           $itemObj[$attributes[$i]['Name']] = is_array($attributes[$i]['Value']) ? "" : $attributes[$i]['Value']; 
          } 
          $result[] = $itemObj; 
         } 
         if (isset($responseObj['SelectResult']['NextToken'])) { 
          $this->nextToken = $responseObj['SelectResult']['NextToken']; 
         } else { 
          $this->nextToken = ''; 
         } 
        } 
       } 
      } 
      return $result; 
     } 
     } catch (exception $ex) { 
      log_message('error', $ex->getMessage()); 
     } 

    }