[英]Converting XML to json using php
我對 XML 不太熟悉。你們能幫我用 php 把這個 xml 轉換成 json 嗎? 這是一個 API 響應。
<?xml version="1.0" encoding="utf-8"?>
<ecomexpress-objects version="1.0">
<object pk="1" model="awb">
<field type="BigIntegerField" name="awb_number">115979601</field>
<field type="CharField" name="orderid">001</field>
<field type="FloatField" name="actual_weight">0.8</field>
<field type="CharField" name="origin">DELHI-DLW</field>
<field type="CharField" name="destination">DELHI-DLW</field>
<field type="CharField" name="current_location_name">DELHI-DLW</field>
<field type="CharField" name="current_location_code">DLW</field>
<field type="CharField" name="customer">Freshbells - 471459</field>
<field type="CharField" name="consignee">Forward</field>
<field type="CharField" name="pickupdate"></field>
<field type="CharField" name="status">Shipment Uploaded</field>
<field type="CharField" name="tracking_status">Shipment Not Handed over</field>
<field type="CharField" name="reason_code"></field>
<field type="CharField" name="reason_code_description"></field>
<field type="CharField" name="reason_code_number">001</field>
<field type="CharField" name="receiver"></field>
<field type="CharField" name="lat">0.0000000</field>
<field type="CharField" name="long">0.0000000</field>
<field type="CharField" name="rev_pickup_signature" ></field>
<field type="CharField" name="rev_pickup_packed_image" ></field>
<field type="CharField" name="rev_pickup_open_image" ></field>
</ecomexpress-objects>
我嘗試過在這里找到這么多解決方案。 但這是行不通的。
這個 XML 似乎序列化數據 model 對象。 將它們讀入stdClass
對象相當容易。
// bootstrap DOM+Xpath
$document = new DOMDocument();
$document->loadXML(getXMLString());
$xpath = new DOMXpath($document);
$objects = [];
// iterate object elements
foreach ($xpath->evaluate('/ecomexpress-objects/object') as $objectNode) {
$object = new stdClass();
// iterate field elements
foreach ($xpath->evaluate('field', $objectNode) as $fieldNode) {
// read attributes
$name = $fieldNode->getAttribute('name');
$type = $fieldNode->getAttribute('type');
// read field content and cast according to type
switch ($type) {
case 'BigIntegerField':
$object->{$name} = (int)$fieldNode->textContent;
break;
case 'FloatField':
$object->{$name} = (float)$fieldNode->textContent;
break;
default:
$object->{$name} = $fieldNode->textContent;
}
}
$objects[] = $object;
}
echo json_encode($objects, JSON_PRETTY_PRINT);
function getXMLString(): string {
return <<<'XML'
<?xml version="1.0" encoding="utf-8"?>
<ecomexpress-objects version="1.0">
<object pk="1" model="awb">
<field type="BigIntegerField" name="awb_number">115979601</field>
<field type="CharField" name="orderid">001</field>
<field type="FloatField" name="actual_weight">0.8</field>
<field type="CharField" name="origin">DELHI-DLW</field>
<field type="CharField" name="destination">DELHI-DLW</field>
<field type="CharField" name="current_location_name">DELHI-DLW</field>
<field type="CharField" name="current_location_code">DLW</field>
<field type="CharField" name="customer">Freshbells - 471459</field>
<field type="CharField" name="consignee">Forward</field>
<field type="CharField" name="pickupdate"></field>
<field type="CharField" name="status">Shipment Uploaded</field>
<field type="CharField" name="tracking_status">Shipment Not Handed over</field>
<field type="CharField" name="reason_code"></field>
<field type="CharField" name="reason_code_description"></field>
<field type="CharField" name="reason_code_number">001</field>
<field type="CharField" name="receiver"></field>
<field type="CharField" name="lat">0.0000000</field>
<field type="CharField" name="long">0.0000000</field>
<field type="CharField" name="rev_pickup_signature" ></field>
<field type="CharField" name="rev_pickup_packed_image" ></field>
<field type="CharField" name="rev_pickup_open_image" ></field>
</object>
</ecomexpress-objects>
XML;
}
Output:
[
{
"awb_number": 115979601,
"orderid": "001",
"actual_weight": 0.8,
"origin": "DELHI-DLW",
"destination": "DELHI-DLW",
"current_location_name": "DELHI-DLW",
"current_location_code": "DLW",
"customer": "Freshbells - 471459",
"consignee": "Forward",
"pickupdate": "",
"status": "Shipment Uploaded",
"tracking_status": "Shipment Not Handed over",
"reason_code": "",
"reason_code_description": "",
"reason_code_number": "001",
"receiver": "",
"lat": "0.0000000",
"long": "0.0000000",
"rev_pickup_signature": "",
"rev_pickup_packed_image": "",
"rev_pickup_open_image": ""
}
]
可以使用代碼中的實際 model 類擴展此方法。 這是一個非常基本的方法(沒有錯誤處理):
// define a class for the model
class AWB implements JsonSerializable {
public readonly int $awb_number;
public readonly string $orderid;
public readonly float $actual_weight;
public function __construct(stdClass $values) {
foreach ((array)$values as $name => $value) {
if (property_exists($this, $name)) {
$this->{$name} = $value;
}
}
}
public function jsonSerialize(): mixed {
return get_object_vars($this);
}
}
// mapping array
$models = [
'awb' => AWB::class
];
$document = new DOMDocument();
$document->loadXML(getXMLString());
$xpath = new DOMXpath($document);
$objects = [];
foreach ($xpath->evaluate('/ecomexpress-objects/object') as $objectNode) {
$object = new stdClass();
foreach ($xpath->evaluate('field', $objectNode) as $fieldNode) {
// read field values - just like the previous example
}
// map model name to class
$class = $models[$objectNode->getAttribute('model')];
$objects[] = new $class($object);
}
echo json_encode($objects, JSON_PRETTY_PRINT);
Output:
[
{
"awb_number": 115979601,
"orderid": "001",
"actual_weight": 0.8
}
]
PHP 屬性也可用於 map 屬性的字段名稱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.