我需要返回一個轉換爲JSON對象的SimpleXML對象,以便在JavaScript中使用它。問題是任何具有值的對象都沒有屬性。PHP SimpleXML對象中消失的屬性?
作爲一個例子:
<customer editable="true" maxChars="9" valueType="numeric">69236</customer>
變爲在SimpleXML的對象:
"customer":"69236"
在哪裏@attributes
對象?
我需要返回一個轉換爲JSON對象的SimpleXML對象,以便在JavaScript中使用它。問題是任何具有值的對象都沒有屬性。PHP SimpleXML對象中消失的屬性?
作爲一個例子:
<customer editable="true" maxChars="9" valueType="numeric">69236</customer>
變爲在SimpleXML的對象:
"customer":"69236"
在哪裏@attributes
對象?
下面是一些代碼來遍歷屬性,並構造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);
好運屬性
這推動我瘋了幾次。當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);
這將保留的屬性和嵌套的文本值在一個孩子節點。
我意識到這是一箇舊帖子,但如果它證明有用。以下內容擴展了@ ryanmcdonnell的解決方案,以處理任何標籤而不是硬編碼標籤。希望它可以幫助某人。
$str = preg_replace('/<([^ ]+) ([^>]*)>([^<>]*)<\/\\1>/i', '<$1 $2><value>$3</value></$1>', $result);
主要不同之處在於它取代/<customer
與/<([^ ]+)
,然後用</customer>
</\\1>
告訴它來匹配圖案中的第一個元素的搜索的一部分。
那麼它只是調整佔位符($1
,$2
,$3
)考慮到一個事實,即有三子匹配的現在而不是兩個。
如果元素中存在例如CDATA塊,則也會失敗,如下所示:
這是一個老問題,但我發現了一些工作整潔的東西 - 解析成DOMNode對象。
// $customer contains the SimpleXMLElement
$customerDom = dom_import_simplexml($customer);
var_dump($customerDom->getAttribute('numeric'));
將顯示:
string 'numeric'
如果有例如在元件CDATA塊,像這樣該失敗:<![CDATA [黑色]]><列名稱= 「彩色」> – 2016-06-01 13:13:29
對我來說,解決方案是在循環xml對象時顯式調用' - > children()'。如果我沒有,屬性就消失了。 – 2016-08-10 10:05:45