Erzwingen eines SimpleXML-Objekts zu einer Zeichenfolge, unabhängig vom Kontext

78

Angenommen, ich habe XML wie dieses

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

Der folgende Code macht das, was ich will, indem er den Titel als Zeichenfolge ausgibt

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

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

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

Ich habe so daran gearbeitet

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

aber das scheint hässlich.

Was ist der beste Weg, um ein SimpleXML-Objekt unabhängig vom Kontext in eine Zeichenfolge zu zwingen?

Mark Biek
quelle
Ich habe mehrere Anfragen an PHP gesendet, um etwas Ähnliches wie SOAP_SINGLE_ELEMENT_ARRAYS zu implementieren, und würde andere dazu ermutigen, dasselbe zu tun. SOAP_SINGLE_ELEMENT_ARRAYS erzwingt, dass Elemente, die mehr als eine Zeichenfolge enthalten könnten, immer nur als Zeichenfolgen analysiert werden. Natürlich müssen Sie, wie andere bereits erwähnt haben, wissen, was Sie zurückbekommen, aber ich bin immer wieder auf Probleme mit .NET SOAP-Servern gestoßen, für die die WSDL (nach den "magischen" Standardeinstellungen von .NET) jede Zeichenfolge als Prototyp erstellt hat gemischt oder eine Reihe von Zeichenfolgen. Anstelle von current () 'ing oder
typecasting

Antworten:

151

Geben Sie das SimpleXMLObject in eine Zeichenfolge ein:

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

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

Aron Rotteveel
quelle
Das ist sauberer als mit einem Sprintf. Ich mag es
Mark Biek
5
Beachten Sie, dass die Verwendung einer Funktion, die Zeichenfolgenargumente akzeptiert, diese Typumwandlung automatisch ausführt (z. B. echo, str_replace, substr).
Ross
3
$ foo = (string) $ xml-> channel-> item-> title; ist das, wonach ich gesucht habe, da ich kein Array brauche. Vielen Dank.
Drazisil
1
+100 du hast gerade meinen Abend gemacht! Ich bin neu in SimpleXMLObject. Die Variablen, die ich daraus extrahiert hatte, wurden gut auf dem Bildschirm gedruckt, aber meine DB-Abfrage schlug fehl ... seufz! Seit wann wurde PHP streng getippt? ;-)
MegaSteve4
1
@ megaSteve4 "Seit wann wurde PHP streng getippt?" - Genau deshalb muss dies nicht geschehen: Die meisten Funktionen haben keinen definierten Typkontext und können daher nicht implizit in diesen Typ umgewandelt werden. Natürlich können sie ihre Eingabeparameter explizit umwandeln, weshalb substret al. Arbeiten. Es ist jedoch sicherer, die Besetzung so früh wie möglich durchzuführen, damit Sie wissen, dass alle Funktionen die erwarteten Daten sehen.
IMSoP
22

Sie können die PHP-Funktion verwenden

strval();

Diese Funktion gibt die Zeichenfolgenwerte des an sie übergebenen Parameters zurück.

Zaje
quelle
3
@ Mark Biek: Es funktioniert mit Objekten, die __toString()implementiert wurden, und insbesondere in diesem Fall funktioniert es sehr gut mit Objekten vom Typ SimpleXMLElement. Sie können es mit der stringBesetzung in der akzeptierten Antwort vergleichen. strval()ist eine praktische Rückruffunktion, die häufig in Verbindung mit array_map()und iterator_to_array($simpleXMLElement, false)oder verwendet wird SimpleXMLElement::xpath().
hakre
9

Es gibt die native SimpleXML-Methode SimpleXMLElement :: asXML. Je nach Parameter schreibt SimpleXMLElement in eine XML 1.0-Datei oder nur in eine Zeichenfolge:

$xml = new SimpleXMLElement($string);
$validfilename = '/temp/mylist.xml';
$xml->asXML($validfilename);    // to a file
echo $xml->asXML();             // to a string
Gemischter Fall
quelle
Ich erhalte den Aufruf einer undefinierten Funktion als XML, also schätze ich, dass dies jetzt veraltet ist.
Eoin
1
@Eoin Hmm ... Habe gerade mein Beispiel getestet, es funktioniert immer noch gut mit nativer PHP 7.3-Installation
Mixed Case
Ich muss ein anderes Problem gehabt haben. Entschuldigen Sie. Ich habe mein Problem jetzt behoben :)
Eoin
3

Ein anderer hässlicher Weg, es zu tun:

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

Es funktioniert, aber es ist nicht schön.

Mikepote
quelle
3

Die akzeptierte Antwort gibt tatsächlich ein Array zurück, das eine Zeichenfolge enthält, die nicht genau dem entspricht, was OP angefordert hat (eine Zeichenfolge). Um diese Antwort zu erweitern, verwenden Sie:

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

Was das einzelne Element des Arrays zurückgibt, eine Zeichenfolge.

DJ Far
quelle
2

Um XML-Daten in ein PHP-Array zu bekommen, gehen Sie folgendermaßen vor:

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

Um ein Kind zu bekommen, gehen Sie einfach wie folgt vor:

$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 jede Ebene erweitern, bis Sie das erhalten, was Sie möchten. Sie können auch alle Knoten in einem Array ohne die Ebenen oder auf eine beliebige andere Weise zusammenfassen.

Pete
quelle
1

Versuchen Sie es mit strval ($ xml-> channel-> item-> title)

Ariel Ruiz
quelle
0

Ich bin mir nicht sicher, ob sie die Sichtbarkeit der __toString()Methode geändert haben , seit die akzeptierte Antwort geschrieben wurde, aber zu diesem Zeitpunkt funktioniert es gut für mich:

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

AUSGABE:

string(15) "This is title 1"
Billynoah
quelle
0

Es gibt die native SimpleXML-Methode SimpleXMLElement :: asXML. Je nach Parameter schreibt SimpleXMLElement in die XML 1.0-Datei. Ja

$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());
BAVA SHIEK BAREETH
quelle
0

Setzen Sie einfach das ''. Vor jeder Variablen wird sie in einen String konvertiert.

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

kk4You
quelle
-1

Das Folgende ist eine rekursive Funktion, die alle untergeordneten Elemente in a typisiert 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
Tony
quelle