Влияние SimpleXMLElement (передать свойства в контексте записи) - PullRequest
1 голос
/ 10 октября 2011

У меня проблема с SimpleXML. Как и в официальной документации, я хочу сделать это:

<?php
include 'example.php';
$movies = new SimpleXMLElement($xmlstr);

$movies->movie[0]->characters->character[0]->name = 'Miss Coder';

echo $movies->asXML();
?>

Но мой код:

<?php
public function renderMarker($xml, &$html)
{
    $html = ((string) $html) . 'Text to add';
}
?>

с:

$html = object(SimpleXMLElement)#185 (1) {
  ["@attributes"]=>
  array(1) {
    ["id"]=>
    string(5) "title"
  }
}

Но когда я делаю это, в результате я получаю $html = string(12) "Text to add" Кто-нибудь знает обходной путь для этого. Заранее спасибо.

1 Ответ

0 голосов
/ 10 октября 2011

То, что вы пытаетесь достичь, не работает, и для SimpleXML не существует решения для этого.

Каждый объект SimpleXML имеет динамические свойства.Вы получаете к ним доступ, как если бы они были свойством объекта, но на самом деле, каждый раз, когда вы обращаетесь к ним, либо возвращается возвращаемое значение свойства (чтение), либо обновляется что-то еще (запись).

Однако,если вы передаете такие свойства функции, как вы, вы передали только фактическое возвращаемое значение (из чтения), а не само свойство.

Упрощенный пример, который не работает, поскольку $xml->title не передается какпеременная в функцию set_property (нет необходимости добавлять ссылку, это не имеет значения):

$xmlStr = '<root><title></title></root>';

$xml = new SimpleXMLElement($xmlStr);

function set_property(&$prop)
{
   $prop = 'Test';
}

set_property($xml->title);

echo $xml->asXML();

Вывод:

<?xml version="1.0"?>
<root><title/></root>

Как написано, естьнет легкого обходного пути для этого.Один из обходных путей заключается в том, что вы сами создаете объект SimpleXMLProperty, который вы можете передавать в параметрах функции:

/**
 * Encapsulate SimpleXMLElement Property
 */
class SimpleXMLProperty
{
    private $obj, $prop;
    public function __construct(SimpleXMLElement $obj, $property)
    {
        $this->obj = $obj;
        $this->prop = $property;
    }
    public function get()
    {
        return $this->obj->{$this->prop};
    }
    public function set($value)
    {
        $this->obj->{$this->prop} = $value;
    }
}


$xmlStr = '<root><title></title></root>';

$xml = new SimpleXMLElement($xmlStr);

function set_property(SimpleXMLProperty $prop)
{
   $prop->set('Test');
}

$property = new SimpleXMLProperty($xml, 'title');

set_property($property);

echo $xml->asXML();

Вывод:

<?xml version="1.0"?>
<root><title>Test</title></root>

Он инкапсулирует свойство и обращается к нему при чтении и записи.контекст зависит от функции get или set, которая называется ( Demo ).

Но для того, что вы строите, лучше было бы вместо этого заглянуть в DomDocument.У него гораздо более стандартизированный интерфейс для DOM, и вы фактически передаете объекты, например, текстовые узлы.

...