Принуждение объекта 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 в строку независимо от контекста?


person Mark Biek    schedule 06.01.2009    source источник
comment
Я отправил несколько запросов в PHP для реализации чего-то похожего на SOAP_SINGLE_ELEMENT_ARRAYS для этого, и хотел бы призвать других сделать то же самое. SOAP_SINGLE_ELEMENT_ARRAYS заставляет элементы, которые / могут / содержать более одной строки, всегда анализироваться как просто строки. Конечно, как упоминали другие, вам нужно знать, что вы получаете в ответ, но снова и снова я сталкивался с проблемами с серверами .NET SOAP, которые WSDL для (по волшебным значениям .NET по умолчанию) прототипировали каждую строку как смешанную или массив строк. Вместо current () или преобразования типов бит просто возвращает строку   -  person conrad10781    schedule 09.12.2017


Ответы (11)


Приведите SimpleXMLObject в строку:

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

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

person Aron Rotteveel    schedule 06.01.2009
comment
Это чище, чем использование sprintf. мне это нравится - person Mark Biek; 06.01.2009
comment
Обратите внимание, что использование функции, которая принимает строковые аргументы, автоматически выполняет приведение этого типа (например, echo, str_replace, substr). - person Ross; 06.01.2009
comment
Спасибо, Арон, я подумал, что это можно сделать с помощью приведения типов, но это казалось неправильным. Теперь, когда я знаю, что метод _toString является частным, это имеет смысл. - person Neil Aitken; 12.08.2009
comment
$ foo = (строка) $ xml- ›channel-› item- ›title; это то, что я искал, так как мне не нужен массив. Спасибо. - person Drazisil; 01.08.2012
comment
+100 ты только что сделал мой вечер! Я новичок в SimpleXMLObject, вары, которые я извлек из него, отлично «печатались» на экране, но не выполняли мой запрос к БД ... вздох! С каких это пор PHP стал строго типизированным? ;-) - person megaSteve4; 28.10.2012
comment
@ megaSteve4 С каких это пор PHP стал строго типизированным? - именно потому, что этого не должно происходить: большинство функций не имеют определенного контекста типа, поэтому не могут неявно привести к этому типу. Конечно, они могут явно приводить свои входные параметры, поэтому substr и другие работают. Однако безопаснее выполнить приведение как можно раньше, чтобы вы знали, что все функции будут видеть данные, которые они ожидают. - person IMSoP; 21.02.2013

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

strval();

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

person Zaje    schedule 04.02.2009
comment
@Mark Biek: Он действительно работает с объектами, которые реализованы __toString(), и особенно в этом случае, в частности, он очень хорошо работает с объектами типа SimpleXMLElement. Вы можете сравнить это с приведением string в принятом ответе. strval() - удобная функция обратного вызова, которую часто используют вместе с array_map() и _ 6_ или SimpleXMLElement::xpath(). - person hakre; 21.02.2013

Существует собственный метод 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
person Mixed Case    schedule 01.02.2013
comment
Я получаю вызов неопределенной функции asXML, так что я предполагаю, что это уже устарело? - person Eoin; 08.06.2019
comment
@Eoin Хм ... Только что проверил мой пример, он все еще отлично работает с собственной установкой php 7.3 - person Mixed Case; 03.11.2019
comment
У меня, должно быть, была другая проблема. Мои извинения. Я исправил свою проблему сейчас :) - person Eoin; 04.11.2019

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

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

Работает, но некрасиво.

person Mikepote    schedule 13.08.2012

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

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

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

person DJ Far    schedule 07.09.2016

Чтобы получить данные 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-> на каждом уровне, пока не получите то, что хотите. Вы также можете поместить все узлы в один массив без уровней или любым другим способом.

person Pete    schedule 11.07.2011

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

person Ariel Ruiz    schedule 04.07.2017

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

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

ВЫХОД:

string(15) "This is title 1"
person billynoah    schedule 29.09.2017

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

$get_file= read file from path;
$itrate1=$get_file->node;
$html  = $itrate1->richcontent->html;


echo  $itrate1->richcontent->html->body->asXML();
 print_r((string) $itrate1->richcontent->html->body->asXML());
person BAVA SHIEK BAREETH    schedule 23.11.2018

Просто поставьте "". перед любой переменной он будет преобразован в строку.

$ foo = array (''. $ xml-> канал-> элемент-> заголовок);

person kk4You    schedule 03.05.2020

Ниже приведена рекурсивная функция, которая преобразует все элементы с одним дочерним элементом в 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
person Tony    schedule 17.07.2017