在PHP中使用SPL庫中的對象方法進行XML與數組的轉換

雖然說如今不少的服務提供商都會提供 JSON 接口供咱們使用,可是,仍是有很多的服務依然必須使用 XML 做爲接口格式,這就須要咱們來對 XML 格式的數據進行解析轉換。而 PHP 中並無像 json_encode() 、 json_decode() 這樣的函數可以讓咱們方便地進行轉換,因此在操做 XML 數據時,你們每每都須要本身寫代碼來實現。php

今天,咱們介紹的是使用 SPL 擴展庫中的一些對象方法來處理 XML 數據格式的轉換。首先,咱們定義一個類,就至關於封裝一個操做 XML 數據轉換的類,方便咱們未來使用。若是隻是測試效果的話,直接寫下面的函數也是能夠的。node

class ConvertXml{
    // ....
}

XML 轉換爲 PHP 數組

class ConvertXml{
    public function xmlToArray(SimpleXMLIterator $xml): array
    {
        $res = [];

        for ($xml->rewind(); $xml->valid(); $xml->next()) {
            $a = [];
            if (!array_key_exists($xml->key(), $a)) {
                $a[$xml->key()] = [];
            }
            if ($xml->hasChildren()) {
                $a[$xml->key()][] = $this->xmlToArray($xml->current());
            } else {
                $a[$xml->key()] = (array) $xml->current()->attributes();
                $a[$xml->key()]['value'] = strval($xml->current());
            }
            $res[] = $a;
        }

        return $res;
    }

    // .....
}

$wsdl = 'http://flash.weather.com.cn/wmaps/xml/china.xml';

$xml = new SimpleXMLIterator($wsdl, 0, true);
$convert = new ConvertXml();
// var_dump($convert->xmlToArray($xml));
// array(37) {
//     [0]=>
//     array(1) {
//       ["city"]=>
//       array(2) {
//         ["@attributes"]=>
//         array(9) {
//           ["quName"]=>
//           string(9) "黑龍江"
//           ["pyName"]=>
//           string(12) "heilongjiang"
//           ["cityname"]=>
//           string(9) "哈爾濱"
//           ["state1"]=>
//           string(1) "7"
//           ["state2"]=>
//           string(1) "3"
//           ["stateDetailed"]=>
//           string(15) "小雨轉陣雨"
//           ["tem1"]=>
//           string(2) "21"
//           ["tem2"]=>
//           string(2) "16"
//           ["windState"]=>
//           string(21) "南風6-7級轉4-5級"
//         }
//         ["value"]=>
//         string(0) ""
//       }
//     }
//     [1]=>
//     array(1) {
//       ["city"]=>
//       array(2) {

在這裏,咱們使用的是 SimpleXMLIterator 對象。從名稱中就能夠看出,它的做用是生成能夠遍歷的 SimpleXMLElement 對象。第一個參數是格式正確的 XML 文本或者連接地址。第二個參數是一些選項參數,這裏咱們直接給 0 就能夠了。第三個參數則是指明第一個參數是不是連接地址,這裏咱們給 true 。git

咱們在客戶端生成了 SimpleXMLIterator 對象,並傳遞到 xmlToArray() 方法中。這樣 SimpleXMLIterator 對象就能讓咱們遍歷各個結點了,接下來的事情就很簡單了,咱們只須要判斷一下結點是否還有子結點,若是有子結點則遞歸調用當前這個方法。若是沒有子結點了,就獲取結點的屬性和內容。github

這個測試連接是獲取天氣信息的,返回的內容中每一個結點都只有屬性沒有內容,體如今轉換後的數組中就是 value 字段都是空的。編程

PHP 數組或對象轉換爲 XML

class ConvertXml{

    // ......

    const UNKNOWN_KEY = 'unknow';
    
    public function arrayToXml(array $a)
    {
        $xml = new SimpleXMLElement('<?xml version="1.0" standalone="yes"?><root></root>');
        $this->phpToXml($a, $xml);
        return $xml->asXML();
    }
    
    protected function phpToXml($value, &$xml)
    {
        $node = $value;
        if (is_object($node)) {
            $node = get_object_vars($node);
        }
        if (is_array($node)) {
            foreach ($node as $k => $v) {
                if (is_numeric($k)) {
                    $k = 'number' . $k;
                }
                if (!is_array($v) && !is_object($v)) {
                    $xml->addChild($k, $v);
                } else {
                    $newNode = $xml->addChild($k);
                    $this->phpToXml($v, $newNode);
                }
            }
        } else {
            $xml->addChild(self::UNKNOWN_KEY, $node);
        }
    }
}

var_dump($convert->arrayToXml($data));
// string(84454) "<?xml version="1.0" standalone="yes"?>
// <root><unlikely-outliner><subject><mongo-db><outline><chapter><getting-started><number0>  ...........
// "

咱們在 arrayToXml() 中,先使用 SimpleXMLElement 對象建立了一個基本的根結點結構。而後使用 phpToXml() 方法來建立全部結點。爲何要拆成兩個方法呢?由於 phpToXml() 方法是須要遞歸調用的,在每次遞歸的時候咱們不須要從新的去建立根結點,只須要在根結點下面使用 addChild() 添加子結點就能夠了。json

在 phpToXml() 的代碼中,咱們還使用了 get_object_vars() 函數。就是當傳遞進來的數組項內容是對象時,經過這個函數能夠獲取對象的全部屬性。若是將對象看作是一個數組的話,每一個屬性值就是它的鍵值對。數組

在對每一個鍵值遍歷時,咱們判斷當前的鍵對應的內容是不是數組或者是對象。若是不是這兩種形式的內容的話,就直接將當前的內容添加爲當前結點的子結點。若是是數組或對象的話,就繼續遞歸地添加直到數組內容所有遍歷完成。函數

測試的 $data 內容很是長,你們能夠直接經過測試代碼的連接去 Github 上查閱。學習

總結

這篇文章的內容是簡單的學習了一個 SPL 擴展庫中對於 XML 操做的兩個對象的使用。經過它們,咱們能夠方便的轉換 XML 數據格式。固然,對於 XML 的格式轉換來講,咱們還有其它的方法,之後學到了再說!測試

測試代碼:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202009/source/在PHP中使用SPL庫中的對象方法進行XML與數組的轉換.php

參考文檔:

《PHP7編程實戰》

各自媒體平臺都可搜索【硬核項目經理】

相關文章
相關標籤/搜索