PHP数组转XML,支持多维数组+属性+CDATA+格式化+数字下标处理+递归

特性

  1. 多维数据
  2. 可解析节点属性(请看最下面的示例中$orders的_attrs,和 pages='9' date='20190412'>)
  3. CDATA标签开关
  4. 可控缩进、换行 ($indent等于非空字符串时,会自动格式化+换行)
  5. 强制文字输出,忽略CDATA标签(例如12/8/2011 21:56 PM, 方法:'OrderDate' => 'force_value:::12/8/2011 21:56 PM',)
  6. 强制文字输出,不带标签(例如强制输出一段文字, 方法:'anyUniqueKey' => 'force_only_value:::',)
  7. 等等

 

前言

自己写的函数。请留意以下的约定:

  1. 节点的属性 pages='9'>的实现,需要使用特定的‘_attrs’子数组来定义,不限数量;
  2. 数字下标处理:重复的order标签,例如<orders><order>..第一个..order><order>..第二个..order>orders>,需要数组orders下面定义一个纯数字下标的数组order,具体请看最下面的实例和结果;
  3. 函数写得有点费脑,转载时还请添加出处,谢谢理解。
  4. 拿去class里面用的话,需要修改函数中4处"array_to_xml"的递归调用为$this->array_to_xml()

 

函数

/**
 * array_to_xml 可格式化数组转xml
 * 
 * @author Rudon <[email protected]>
 * 
 * 
 * 【支持】
 * 1.多维数据
 * 2.可解析属性标签(请看示例$orders的_attrs,和)
 * 3.CDATA标签开关
 * 4.可控缩进、换行
 * 5.强制文字输出,忽略CDATA标签(例如12/8/2011 21:56 PM, 方法:'OrderDate' => 'force_value:::12/8/2011 21:56 PM',)
 * 6.强制文字输出,不带标签(例如强制输出一段文字, 方法:'anyKey' => 'force_only_value:::',)
 * 
 * 
 * 【注意】
 * 1. 不允许在$array的第一维数组全部使用纯数字的下标
 * 2. 函数报错,是直接die('message');
 * 3. 尚未妥善处理‘对象’变量
 * 
 * 【实例】
 * (如果全是纯数字的下标就当作数组,否则当作对象)
 * $data = array(
 *   'orders' => array( 
 *      '_attrs' => array(
 *          'pages' => 9,
 *          'date' => '20190412'
 *      ),
 *      'order' => array(
 *          0 => array(
 *              'id' => 1000,
 *              'customer' => 'Michael Jackson',
 *              'products' => array(
 *                  0 => array(
 *                  'pid' => 86572,
 *                  'name' => 'Hat in red'
 *                  )
 *              )
 *          ),
 *          1 => array(
 *              'id' => 1001,
 *              'customer' => 'John',
 *              'products' => array(
 *                  0 => array(
 *                      'pid' => 471,
 *                      'name' => 'Mooncake'
 *                  )
 *              )
 *          )   // #1
 *      )       // order
 *   )          // orders
 * );           // $array
 * 
 * 
 * 
 */
function array_to_xml ($array, $current_depth = -1, $is_getting_more_info = false, $cdata_enabled = true, $indent = '  ', $force_key = '') {
    $return = '';
    $ch = '';
    $body = '';
    $labels_attrs = '_attrs';
    $current_indent = str_repeat($indent, max(0, $current_depth));
    $eol = ($indent != '')? PHP_EOL : ''; // End of line

    /* Special case: $is_getting_more_info */
    if($is_getting_more_info){
        $return = array(
            'attr_str_for_parent' => '',
            'is_num_keys_only_for_itself' => false,
            'checking_data' => $array
        );

        $attrs_str = ''; // Reset
        if(is_array($array) && key_exists($labels_attrs, $array) && count($array[$labels_attrs])){
            $attrs_arr = $array[$labels_attrs];
            foreach ($attrs_arr as $ak => $av) {
                $attrs_str .= ' '.$ak . '='. "'{$av}'";
            }
        }
        $return['attr_str_for_parent'] = $attrs_str;


        if(is_array($array)){
            $is_num_keys_only = true;
            foreach ($array as $k => $v) {
                if($k != $labels_attrs && !is_int($k)){
                    $is_num_keys_only = false;
                }
            }
            $return['is_num_keys_only_for_itself'] = $is_num_keys_only;

        }
        return $return;
    }


    /* Go */
    if(!is_array($array)){
        /* Not an array */
        if(is_string($array)){
            $body = ($cdata_enabled)? $ch.$array.$cf : $array;
            if($array == ''){
                $body = $array;
            }

        } elseif (is_bool($array)) {
            $body = ($array)? 'TRUE':'FALSE';

        } elseif (is_null($array)) {
            $body = '';

        } elseif (is_object($array)) {
            $body = ($cdata_enabled)? $ch. json_encode($array) .$cf : json_encode($array);

        } else {
            $body = $array;
        }

        /* Special case: 'anyKey' => 'force_only_value:::' */
        if(is_string($array) && stripos($array, 'force_only_value:::') === 0){
            $body = $array;
        } elseif (is_string($array) && stripos($array, 'force_value:::') === 0) {
            $body = $array;
        }

        /* Value only */
        $return = $body;

    } else {
        /* Is Array */
        $depth_for_son = $current_depth + 1;
        $indent_for_itself = str_repeat($indent, max(0, $current_depth));
        $indent_for_son = str_repeat($indent, max(0, $depth_for_son));

        $more_info_for_itself = array_to_xml($array, $current_depth, true);
        if(key_exists($labels_attrs, $array)){
            unset($array[$labels_attrs]);
        }

        $return = '';
        foreach ($array as $k => $v) {
            $more_info_for_son = array_to_xml($v, $depth_for_son, true);
            $tag_header_for_son = '<'.$k.$more_info_for_son['attr_str_for_parent'].'>';
            $tag_footer_for_son = '';

            if($more_info_for_son['is_num_keys_only_for_itself']){
                $body_for_son = array_to_xml($v, $current_depth, false, $cdata_enabled, $indent, $k);
                $return .= $body_for_son;

            } else {
                if($force_key != ''){
                    $tag_header_for_son = '<'.$force_key.$more_info_for_son['attr_str_for_parent'].'>';
                    $tag_footer_for_son = '';
                }
                $body_for_son = array_to_xml($v, $depth_for_son, false, $cdata_enabled, $indent);
                if(is_array($v)){
                    $return .= $indent_for_son.$tag_header_for_son.$eol.$body_for_son.$indent_for_son.$tag_footer_for_son;

                } else {
                    $new_row = $indent_for_son.$tag_header_for_son.$body_for_son.$tag_footer_for_son;

                    /* Special case: 'anyKey' => 'force_only_value:::' */
                    if(is_string($body_for_son) && stripos($body_for_son, 'force_only_value:::') === 0){
                        $new_row = $indent_for_son . str_ireplace('force_only_value:::', '', $body_for_son);
                    } elseif (is_string($body_for_son) && stripos($body_for_son, 'force_value:::') === 0) {
                        $new_row = $indent_for_son.$tag_header_for_son.str_ireplace('force_value:::', '', $body_for_son).$tag_footer_for_son;;
                    }

                    $return .= $new_row;

                }
            }
            $return .= $eol;
        }

    }
    return $return;
}

 

实例及结果

 'force_only_value:::',
        'orders' => array(
            '_attrs' => array(
                'pages' => 10
            ),
            'Order' => array(
                0 => array(
                    'OrderID' => '123456',
                    'OrderNumber' => 'ABC123',
                    'OrderDate' => 'force_value:::12/8/2011 21:56 PM',
                    'OrderStatus' => 'paid',
                    'LastModified' => 'force_value:::12/8/2011 12:56 PM',
                    'ShippingMethod' => 'USPSPriorityMail',
                    'PaymentMethod' => 'Credit Card',
                    'OrderTotal' => 'force_value:::123.45',
                    'TaxAmount' => 'force_value:::0.00',
                    'ShippingAmount' => 'force_value:::4.50',
                    'CustomerNotes' => 'Please make sure it gets here by Dec. 22nd!',
                    'InternalNotes' => 'Ship by December 18th via Priority Mail.',
                    'Gift' => false,
                    'GiftMessage' => '',
                    'CustomField1' => '',
                    'CustomField2' => '',
                    'CustomField3' => '',
                    'Customer' => array(
                        'CustomerCode' => '[email protected]',
                        'BillTo' => array(
                            'Name' => 'The President',
                            'Company' => 'US Govt',
                            'Phone' => '512-555-5555',
                            'Email' => '[email protected]',
                        ),
                        'ShipTo' => array(
                            'Name' => 'The President',
                            'Company' => 'US Govt',
                            'Address1' => '1600 Pennsylvania Ave',
                            'Address2' => '',
                            'City' => 'Washington',
                            'State' => 'DC',
                            'PostalCode' => '20500',
                            'Country' => 'US',
                            'Phone' => '512-555-5555'
                        )
                    ),
                    'Items' => array(
                        'Item' => array(
                            0 => array(
                                'SKU' => 'FD88821',
                                'Name' => 'My Product Name',
                                'ImageUrl' => 'http://www.mystore.com/products/12345.jpg',
                                'Weight' => 8,
                                'WeightUnits' => 'force_value:::Ounces',
                                'Quantity' => 2,
                                'UnitPrice' => 'force_value:::13.99',
                                'Location' => 'A1-B2',
                                'Options' => array(
                                    'Option' => array(
                                        0 => array(
                                            'Name' => 'Size',
                                            'Value' => 'Large',
                                            'Weight' => 10
                                        ),
                                        1 => array(
                                            'Name' => 'Color',
                                            'Value' => 'Green',
                                            'Weight' => 5
                                        )
                                    )
                                ),
                            ),
                            1 => array(
                                'SKU' => '',
                                'Name' => '$10 OFF',
                                'Quantity' => 1,
                                'UnitPrice' => 'force_value:::-10.00',
                                'Adjustment' => true
                            )
                        )
                    )
                ),
            )
        )
    );
    
    
    // array_to_xml ($array, $current_depth = -1, $is_getting_more_info = false, $cdata_enabled = true, $indent = '  ', $force_key = ''
    $xml = array_to_xml($data);
    
    
    $xml = htmlspecialchars($xml); // 强制显示所有的内容
    echo '
';
    echo $xml;
    echo '
'; die();

 

谢谢使用~

你可能感兴趣的:(PHP,常识)