PHP:将对象解析为XML(带属性)

时间:2018-05-29 14:06:48

标签: php xml

这是我要解析为XML的php对象。

class HotelType
{
    public $Provider = null;
    public $BookingCode = null;
}

不幸的是输出看起来像这样:

<Hotel>
    <Provider>Company</Provider>
    <BookingCode>123</BookingCode>
</Hotel>

但我想要实现的目标如下:

<Hotel Provider="Company">
    <BookingCode>123</BookingCode>
</Hotel>

最后这是我使用的XMLSerializer类:

class XMLSerializer {

// functions adopted from http://www.sean-barton.co.uk/2009/03/turning-an-array-or-object-into-xml-using-php/

public static function generateValidXmlFromObj($obj, $node_block='nodes', $node_name='node') {
    $arr = get_object_vars($obj);
    return self::generateValidXmlFromArray($arr, $node_block, $node_name);
}

public static function generateValidXmlFromArray($array, $node_block='nodes', $node_name='node') {
    $xml = '<?xml version="1.0" encoding="UTF-8" ?>';

    $xml .= '<' . $node_block . '>';
    $xml .= self::generateXmlFromArray($array, $node_name);
    $xml .= '</' . $node_block . '>';

    return $xml;
}

private static function generateXmlFromArray($array, $node_name) {
    $xml = '';

    if (is_array($array) || is_object($array)) {
        foreach ($array as $key=>$value) {
            if (is_numeric($key)) {
                $key = $node_name;
            }

            $xml .= '<' . $key . '>' . self::generateXmlFromArray($value, $node_name) . '</' . $key . '>';
        }
    } else {
        $xml = htmlspecialchars($array, ENT_QUOTES);
    }

    return $xml;
}
}

我的对象应该如何获得xml属性?

2 个答案:

答案 0 :(得分:0)

您可以安装PEARXML_Serializer

  • Here手册安装PEAR。
  • Here手册,如何安装 梨包。
  • Here链接到XML_Serializer包。

如果你在ubuntu上安装了PEAR,只需输入console:

sudo pear install XML_Serializer

XML_Serializer 的代码示例:

<?php
header("Content-type: text/xml");

require_once 'XML/Serializer.php';

class HotelType
{
    public $bookingCode = null;
}   

class objectToXml
{
    private $rootAttributes = [];
    private $serializer;

    public function __construct()
    {
         $this->serializer = new XML_Serializer();
    }

    public function convert($object)
    {
        if ($this->serializer->serialize($object)) {
            return $this->serializer->getSerializedData();
        }

        return '';
    }

    public function addRootAttribute($name, $value)
    {
        $this->rootAttributes[$name] = $value;
        $this->serializer->setOption(XML_SERIALIZER_OPTION_ROOT_ATTRIBS, $this->rootAttributes);
    }
}

$hotelType = new HotelType();
$hotelType->bookingCode = "booking";

$providerName = 'name';
$providerValue = 'value';

$providerName1 = 'name1';
$providerValue1 = 'value2';

$objectToXml = new ObjectToXml();
$objectToXml->addRootAttribute($providerName, $providerValue);
$objectToXml->addRootAttribute($providerName1, $providerValue1);
echo $objectToXml->convert($hotelType);

<强>结果

<HotelType name="value" name1="value2">
    <bookingCode>booking</bookingCode>
</HotelType>

答案 1 :(得分:0)

由于我没有找到一个简单的解决方案,我自己扩展了这个方法。

如果有人需要,这里是源代码:

private static function generateXmlFromArray($array, $node_name) {
    $xml = '';

    if (is_array($array) || is_object($array)) {
        foreach ($array as $key=>$value) {
            if($value != null){
                if (is_numeric($key)) {
                    $key = rtrim($node_name, "s"); //remove the plural if array
                }
                if(is_array($value) || is_object($value)){
                    $xml .= '<' . $key;
                    foreach ($value as $nextKey => $nextValue) {
                        if(strpos($nextKey, "__") !== false && $nextValue != null){
                            $xml .= ' ' . substr($nextKey, 2) . '="' . $nextValue . '"' ;
                            if(is_object($value)) $value->$nextKey = null; 
                            else if(is_array($value)) $value[$nextKey] = null;
                        }
                    }
                    $xml .= '>' . self::generateXmlFromArray($value, $key) . '</' . $key . '>';
                }else if($key == "_"){
                    $xml = self::generateXmlFromArray($value, $key);
                }else{
                    $xml .= '<' . $key . '>' . self::generateXmlFromArray($value, $key) . '</' . $key . '>';   
                }
            }else self::generateXmlFromArray($value, $key);
        }
    } else {
        $xml = htmlspecialchars($array, ENT_QUOTES);
    }
    return $xml;
}

如果您重命名变量,请执行以下操作:

class HotelType
{
    public $__Provider = null; //the "__" prefix will be removed in the xml
    public $BookingCode = null;
}

它将产生预期的输出:

<Hotel Provider="Company">
    <BookingCode>123</BookingCode>
</Hotel>