Принуждение объекта 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"