SimpleXMLElement affectation (pass properties in write context)
I've got an issue with SimpleXML. Like in the official documentation, I want to do this :
<?php
include 'example.php';
$movies = new SimpleXMLElement($xmlstr);
$movies->movie[0]->characters->character[0]->name = 'Miss Coder';
echo $movies->asXML();
?>
But my code is :
<?php
public function renderMarker($xml, &$html)
{
$html = ((string) $html) . 'Text to add';
}
?>
with :
$html = object(SimpleXMLElement)#185 (1) {
["@attributes"]=>
array(1) {
["id"]=>
string(5) "title"
}
}
But when I do this, 开发者_开发问答I've got $html = string(12) "Text to add"
as a result.
Does anybody knows a workarround for this.
Thanks in advance.
What you try to achieve does not work and there is no solution for that with SimpleXML.
Each SimpleXML object has dynamic properties. You access them as-if they were a property of an object, but infact, each time you access them, either the property's return value is given (reading) or something else is updated (writing).
However, if you pass such properties to a function like you did, you only passed the actual return value (from reading) and not the property itself.
Simpliefied example which does not work, because $xml->title
is not passed as variable into the set_property
function (there is no need to add a reference, it does not make a difference):
$xmlStr = '<root><title></title></root>';
$xml = new SimpleXMLElement($xmlStr);
function set_property(&$prop)
{
$prop = 'Test';
}
set_property($xml->title);
echo $xml->asXML();
Output:
<?xml version="1.0"?>
<root><title/></root>
As written, there is no easy workaround for it. One workaround is that you create yourself a SimpleXMLProperty object that you can pass around in function parameters:
/**
* 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();
Output:
<?xml version="1.0"?>
<root><title>Test</title></root>
It encapsulates the property and accesses it in read and write context depending on the get or set function called (Demo).
But for what you build, it might be a better thing to look into DomDocument instead. It has a much more standardized interface to the DOM, and you actually pass objects already around, like text-nodes.
精彩评论