2009-01-06 9 views
66

Sagen wir, ich habe einige XML-ähnlicheein SimpleXML Objekt in einen String erzwingen, unabhängig vom Kontext

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

Der folgende Code tut, was ich in möchten, dass sie den Titel als String

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

Hier ist mein Problem. Der folgende Code behandelt den Titel nicht als Zeichenfolge in diesem Kontext, sodass ich ein SimpleXML-Objekt im Array anstelle einer Zeichenfolge erhalte.

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

Ich habe wie diese

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

um daran zu arbeiten, aber das scheint hässlich.

Was ist die beste Methode, um ein SimpleXML-Objekt unabhängig vom Kontext zu einer Zeichenfolge zu erzwingen?

+0

Ich habe mehrere Anfragen an PHP eingereicht etwas ähnliches zu implementieren für diese SOAP_SINGLE_ELEMENT_ARRAYS und würde andere ermutigen, dasselbe zu tun. SOAP_SINGLE_ELEMENT_ARRAYS erzwingt Elemente, die mehr als eine Zeichenfolge analysieren/enthalten können, immer nur als Zeichenfolgen. Natürlich, wie andere erwähnten, müssen Sie wissen, was Sie zurückbekommen, aber immer und immer wieder bin ich auf Probleme mit .NET SOAP-Servern gestoßen, für die die WSDL (nach den "magischen" Standardeinstellungen von .NET) jede Zeichenfolge als Prototypen erstellt hat gemischt oder ein Array von Strings. Anstelle von current() oder typecasting gibt das Bit nur eine Zeichenfolge zurück – conrad10781

Antwort

134

Typecast die SimpleXMLObject in einen String:

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

Der obige Code ruft intern __toString() auf dem SimpleXMLObject. Diese Methode ist nicht öffentlich verfügbar, da sie das Zuordnungsschema von SimpleXMLObject stört, kann jedoch weiterhin auf die oben beschriebene Weise aufgerufen werden.

+0

Das ist sauberer als mit einem Sprintf. Ich mag es –

+5

Beachten Sie, dass das Verwenden einer Funktion, die Zeichenfolgenargumente akzeptiert, dieses Casting automatisch ausführt (z. B. echo, str_replace, substr). – Ross

+0

Dank Aron, ich dachte, eine Typumwandlung wäre der Weg, um dies zu tun, aber es fühlte sich einfach nicht richtig an. Nun, da ich weiß, dass die _toString-Methode privat ist, macht es Sinn. –

15

können Sie die Funktion PHP

strval(); 

dieser Funktion werden die String-Werte des Parameters an sie übergeben zurück.

+1

Leider funktioniert strval() nicht auf Arrays oder Objekten. –

+3

@Mark Biek: Es funktioniert auf Objekte, die '__toString()' implementiert haben und speziell in diesem Fall funktioniert es sehr gut mit Objekten vom Typ 'SimpleXMLElement'. Sie können es mit der "string" -Ausführung in der akzeptierten Antwort vergleichen. 'strval()' ist eine nützliche Callback-Funktion, oft in Verbindung mit ['array_map()'] (http://php.net/array_map) und ['iterator_to_array ($ simpleXMLElement, false)'] (http: // php .net/iterator_to_array) oder 'SimpleXMLElement :: xpath()'. – hakre

2

Um XML-Daten in einen PHP-Array erhalten Sie dies tun:

// 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>"; 

ein Kind Kind bekommt dann dies nur tun:

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

Sie können $ xml-> durch die einzelnen Level erweitern bis Sie bekommen, was Sie wollen Sie können auch alle Knoten in ein Array ohne die Ebenen oder nur über jede andere Art, wie Sie es wollen.

3

Eine andere hässliche Art und Weise, es zu tun:

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

Es funktioniert, aber es ist nicht schön.

9

Es stammt SimpleXML Methode SimpleXMLElement::asXML auf Parameter Abhängig es SimpleXMLElement schreibt 1.0-Datei in XML oder nur in einen String:

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

Die akzeptierte Antwort tatsächlich gibt ein Array einen String enthält, die nicht genau Was OP angefordert (eine Zeichenfolge). auf diese Antwort, die Verwendung zu erweitern:

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

, die das einzelne Element des Arrays zurückgibt, einen String.

1

Try strval ($ xml-> Channel-> item-> title)

0

Das Folgende ist eine rekursive Funktion, die alle Ein-Kind-Elemente zu einem String typisieren wird:

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
// 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 
0

Nicht sicher wenn sie die Sichtbarkeit der __toString() Methode geändert, seit der akzeptierte Antwort geschrieben wurde, aber zu dieser Zeit funktioniert es gut für mich:

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

OUTPUT:

string(15) "This is title 1" 
Verwandte Themen