PHP: преобразовать объект в XML (с атрибутами)

это объект php, который я хочу преобразовать в XML.

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?

Почему вы создаете свой XML вручную? Почему вы не используете существующие библиотеки, такие как ДОМ или SimpleXML?

Progman 29.05.2018 19:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
1
244
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете установить PEAR пакет XML_Serializer.

  • Здесь инструкция по установке PEAR.
  • Здесь мануал, как установить пакеты с грушами.
  • Здесь ссылка на пакет XML_Serializer.

Если вы используете ubuntu и установили PEAR, просто введите в консоли:

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>

К сожалению, это не будет динамически.

RyuZz 30.05.2018 16:42

Обновленный ответ. Вы имели в виду, он не может изменить атрибут после инициализации? Мы можем установить атрибуты после инициализации с помощью serializer->setOption()

zen 30.05.2018 17:07

Если вам нужно преобразовать объект в xml с установленным атрибутом без внешнего вмешательства, вы можете посмотреть документацию XML_Serializer. Я думаю, что у него есть средства для установки атрибутов xml по префиксу или что-то в этом роде.

zen 30.05.2018 17:13
Ответ принят как подходящий

Поскольку я не нашел простого решения, я расширил метод самостоятельно.

Если кому-то это нужно, вот исходный код:

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>

Другие вопросы по теме