簡體   English   中英

使用 php 將 XML 轉換為 json

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM