Принуждение объекта SimpleXML к строке, независимо от контекста

Скажем, у меня есть такой XML, как этот

<channel>
  <item>
    <title>This is title 1</title>
  </item>
</channel>

В приведенном ниже коде делается то, что я хочу, чтобы он выводил заголовок в виде строки

$xml = simplexml_load_string($xmlstring);
echo $xml->channel->item->title;

Вот моя проблема. В приведенном ниже коде не рассматривается заголовок как строка в этом контексте, поэтому я получаю объект SimpleXML в массиве вместо строки.

$foo = array( $xml->channel->item->title );

Я работал над этим, как это

$foo = array( sprintf("%s",$xml->channel->item->title) );

но это кажется уродливым.

Какой лучший способ заставить объект SimpleXML к строке, независимо от контекста?

Ответ 1

Typecast SimpleXMLObject для строки:

$foo = array( (string) $xml->channel->item->title );

Вышеупомянутый код внутренне вызывает __toString() в объекте SimpleXMLObject. Этот метод не является общедоступным, так как он мешает схеме сопоставления объекта SimpleXMLObject, но он все равно может быть вызван указанным выше образом.

Ответ 2

Вы можете использовать функцию PHP

strval();

Эта функция возвращает строковые значения переданного параметра.

Ответ 3

Существует собственный метод SimpleXML SimpleXMLElement:: asXML В зависимости от параметра он записывает SimpleXMLElement в файл xml 1.0 или просто в строку:

$xml = new SimpleXMLElement($string);
$validfilename = '/temp/mylist.xml';
$xml->asXML($validfilename);    // to a file
echo $xml->asXML();             // to a string

Ответ 4

Еще один уродливый способ сделать это:

$foo = array( $xml->channel->item->title."" );

Это работает, но это не очень.

Ответ 5

Чтобы получить XML-данные в php-массив, вы делаете это:

// this gets all the outer levels into an associative php array
$header = array();
foreach($xml->children() as $child)
{
  $header[$child->getName()] = sprintf("%s", $child); 
}
echo "<pre>\n";
print_r($header);
echo "</pre>";

Чтобы получить дочерний ребенок, просто выполните это:

$data = array();
foreach($xml->data->children() as $child)
{
  $header[$child->getName()] = sprintf("%s", $child); 
}
echo "<pre>\n";
print_r($data);
echo "</pre>";

Вы можете развернуть $xml- > через каждый уровень, пока не получите то, что хотите Вы также можете поместить все узлы в один массив без уровней или примерно любой другой способ, которым вы хотите.

Ответ 6

Принятый ответ на самом деле возвращает массив, содержащий строку, что не совсем то, что запрошено OP (строка). Чтобы расширить этот ответ, используйте:

$foo = [ (string) $xml->channel->item->title ][0];

Возвращает единственный элемент массива, строку.

Ответ 7

Попробуйте strval ($ xml- > channel- > item- > title)

Ответ 8

Ниже приведена рекурсивная функция, которая будет отображать все элементы с одним дочерним элементом в String:

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION - CLEAN SIMPLE XML OBJECT
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function cleanSimpleXML($xmlObject = ''){

    // LOOP CHILDREN
    foreach ($xmlObject->children() as $child) {

        // IF CONTAINS MULTIPLE CHILDREN
        if(count($child->children()) > 1 ){

            // RECURSE
            $child = cleanSimpleXML($child);

        }else{

            // CAST
            $child = (string)$child;

        }

    }

    // RETURN CLEAN OBJECT
    return $xmlObject;

} // END FUNCTION

Ответ 9

Не уверен, что они изменили видимость метода __toString(), поскольку принятый ответ был написан, но в это время он отлично подходит для меня:

var_dump($xml->channel->item->title->__toString());

ВЫВОД:

string(15) "This is title 1"