2011-12-19 101 views
7

我需要返回一個轉換爲JSON對象的SimpleXML對象,以便在JavaScript中使用它。問題是任何具有值的對象都沒有屬性。PHP SimpleXML對象中消失的屬性?

作爲一個例子:

<customer editable="true" maxChars="9" valueType="numeric">69236</customer> 

變爲在SimpleXML的對象:

"customer":"69236" 

在哪裏@attributes對象?

回答

-1

下面是一些代碼來遍歷屬性,並構造JSON。如果支持,一個或許多客戶。

如果你的XML看起來是這樣的(或只是一個客戶)

<xml> 
<customer editable="true" maxChars="9" valueType="numeric">69236</customer> 
<customer editable="true" maxChars="9" valueType="numeric">12345</customer> 
<customer editable="true" maxChars="9" valueType="numeric">67890</customer> 
</xml> 

迭代通過像這樣。

try { 
    $xml = simplexml_load_file("customer.xml"); 

    // Find the customer 
    $result = $xml->xpath('/xml/customer'); 

    $bFirstElement = true; 
    echo  "var customers = {\r\n"; 
    while(list(, $node) = each($result)) { 
     if($bFirstElement) { 
      echo "'". $node."':{\r\n"; 
      $bFirstElement = false; 
     } else { 
      echo ",\r\n'". $node."':{\r\n"; 
     } 

     $bFirstAtt = true; 
     foreach($node->attributes() as $a => $b) { 
      if($bFirstAtt) { 
       echo "\t".$a.":'".$b."'"; 
       $bFirstAtt = false; 
      } else { 
       echo ",\r\n\t".$a.":'".$b."'"; 
      } 
     } 
     echo "}"; 
    } 
    echo "\r\n};\r\n"; 
} catch(Exception $e) { 
    echo "Exception on line ".$e->getLine()." of file ".$e->getFile()." : ".$e->getMessage()."<br/>"; 
} 

要產生的JSON結構這樣

var customers = { 
'69236':{ 
    editable:'true', 
    maxChars:'9', 
    valueType:'numeric'}, 
'12345':{ 
    editable:'true', 
    maxChars:'9', 
    valueType:'numeric'}, 
'67890':{ 
    editable:'true', 
    maxChars:'9', 
    valueType:'numeric'} 
}; 

最後,在你的腳本,像這樣訪問

WScript.Echo(customers["12345"].editable); 

好運屬性

7

這推動我瘋了幾次。當SimpleXML遇到只有文本值的節點時,它將刪除所有屬性。我的解決方法是在使用SimpleXML解析之前修改XML。使用一些正則表達式,您可以創建一個包含實際文本值的子節點。例如,在您的情況,您可以更改的XML:

<customer editable="true" maxChars="9" valueType="numeric"><value>69236<value></customer> 

一些示例代碼,假設你的XML字符串在$ STR:

$str = preg_replace('/<customer ([^>]*)>([^<>]*)<\/customer>/i', '<customer $1><value>$2</value></customer>', $str); 
$xml = @simplexml_load_string($str); 

這將保留的屬性和嵌套的文本值在一個孩子節點。

+1

如果有例如在元件CDATA塊,像這樣該失敗:<![CDATA [黑色]]><列名稱= 「彩色」> – 2016-06-01 13:13:29

+0

對我來說,解決方案是在循環xml對象時顯式調用' - > children()'。如果我沒有,屬性就消失了。 – 2016-08-10 10:05:45

3

我意識到這是一箇舊帖子,但如果它證明有用。以下內容擴展了@ ryanmcdonnell的解決方案,以處理任何標籤而不是硬編碼標籤。希望它可以幫助某人。

$str = preg_replace('/<([^ ]+) ([^>]*)>([^<>]*)<\/\\1>/i', '<$1 $2><value>$3</value></$1>', $result); 

主要不同之處在於它取代/<customer/<([^ ]+),然後用</customer></\\1>

告訴它來匹配圖案中的第一個元素的搜索的一部分。

那麼它只是調整佔位符($1$2$3)考慮到一個事實,即有三子匹配的現在而不是兩個。

+1

如果元素中存在例如CDATA塊,則也會失敗,如下所示:<![CDATA [black]]> 2016-06-01 13:13:49

0

這是一個老問題,但我發現了一些工作整潔的東西 - 解析成DOMNode對象。

// $customer contains the SimpleXMLElement 
$customerDom = dom_import_simplexml($customer); 
var_dump($customerDom->getAttribute('numeric')); 

將顯示:

string 'numeric'