XML Rückgabe in Variablen schreiben

Hallo Gemeinde,

nachdem ich nach Tagen erfolgloser Versuche XML-Rückgaben auszulesen und damit Variablen zu füllen gescheitert bin, wende ich mich an Euch. Vielleicht kann mir ja jemand auf die Sprünge helfen.

Hier zur Beschreibung: wenn ich einen HTTP-Post an ein Gerät sende (UPNP) bekomme ich eine Antwort mit der ich Variablen (hier speziell die SingerSessionID) befüllen will. Im Ereignisfenster der Verwaltungskonsole wird mir diese auch brav angezeigt. Mit einem Zwischenschritt des Schreibens einer Datei (Party_Start bzw. Party_State) wird mir zwar die Datei angelegt, sie bleibt aber leer. Mit SimpleXML sollte es dann doch möglich sein Tag-spezifisch Variablen zu befüllen - oder ?

Vielleicht sieht jemand den Fehler - Essentiell ist der Teil bei Party_Start bzw. Party_GetState. Hier sind 2 Auslesevarianten vorhanden. Die Variable 23791 ist die SingerSessionID. Weitere sollten hoffentlich auch per Tag-Erkennung auslesbar sein.

Als Fehlermeldung bekomme ich: Call to a member function asXML() on a non-object (ich nehme an, weil die Datei leer ist) :frowning:

<?

//------------------------------------------------------------------------------
//UPNP_Party
//------------------------------------------------------------------------------

//IPAdresse und Port des primären Device (Host)---------------------------------
$address = "192.168.178.156";
$port = "8080";
$SingerSessionID = Getvalue(23791 /*[Audio\Party_Mode\SingerSessionID]*/);

$file = "http://192.168.178.22:8080/Test.mp3";

//UPNP-Befehle------------------------------------------------------------------

$content_uri='POST /AVTransport/ctrl HTTP/1.1
HOST: '.$address.':'.$port.'
SOAPAction: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"
Content-Length: '.(394+strlen(htmlspecialchars($file))).'
Content-Type: text/xml; charset="utf-8"
CONNECTION: close

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
      <InstanceID>0</InstanceID>
      <CurrentURI>'.$file.'</CurrentURI>
      <CurrentURIMetaData></CurrentURIMetaData>
    </u:SetAVTransportURI>
  </s:Body>
</s:Envelope>';

//URI-Senden--------------------------------------------------------------------

$fp = fsockopen ($address, $port);

fputs ($fp, $content_uri);

fclose($fp);

//Play--------------------------------------------------------------------------

$content_play='POST /AVTransport/ctrl HTTP/1.1
HOST: '.$address.':'.$port.'
Content-Length: 320
Content-Type: text/xml; charset="utf-8"
SOAPAction: "urn:schemas-upnp-org:service:AVTransport:1#Play"
Connection: Close

<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
          s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <s:Body>
    <u:Play xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">
      <InstanceID>0</InstanceID>
      <Speed>1</Speed>
    </u:Play>
  </s:Body>
</s:Envelope>';

//Play-Senden-------------------------------------------------------------------

$fp = fsockopen ($address, $port);

fputs ($fp, $content_play);

fclose($fp);

//Party_GetState------------------------------------------------------------------

$content='POST /Party_Control HTTP/1.1
HOST: '.$address.':'.$port.'
SOAPACTION: "urn:schemas-sony-com:service:Party:1#X_GetState"
CONTENT-TYPE: text/xml; charset="utf-8"
Connection: close
Content-Length: 298

<?xml version="1.0" encoding="utf-8"?>
  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
      <u:X_GetState xmlns:u="urn:schemas-sony-com:service:Party:1"></u:X_GetState>
    </s:Body>
  </s:Envelope>';


//Party_GetState und Log schreiben----------------------------------------------

$fp = fsockopen ($address, $port);
fputs ($fp, $content);

if ($fp)
  {
  while (!feof($fp))
    {
    $buffer = fgets($fp, 4096);
    echo $buffer;
    }
  fclose($fp);
}

	$handle = fopen ("Party_State.xml", "w");
	fputs ($handle, $buffer->asXML());
	fclose ($handle);

$xml = simplexml_load_file("Party_State.xml");

$ret = $xml->SingerSessionID[0];

SetValueString(23791, $ret);


//Party_Leave-------------------------------------------------------------------

$content_party_Leave='POST /Party_Control HTTP/1.1
HOST: '.$address.':'.$port.'
SOAPACTION: "urn:schemas-sony-com:service:Party:1#X_Leave"
CONTENT-TYPE: text/xml; charset="utf-8"
Connection: close
Content-Length: 431
<?xml version="1.0" encoding="utf-8"?>
  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
      <u:X_Leave xmlns:u="urn:schemas-sony-com:service:Party:1">
        <SingerSessionID>'.$SingerSessionID.'</SingerSessionID>
        <ListenerList>uuid:5f9ec1b3-ed59-1900-4530-3c077100c0a1</ListenerList>
      </u:X_Leave>
    </s:Body>
  </s:Envelope>';

//Party_Leave Senden------------------------------------------------------------

$fp = fsockopen ($address, $port);

fputs ($fp, $content_party_Leave);

if ($fp)
  {
  while (!feof($fp))
    {
    $buffer = fgets($fp, 4096);
    echo $buffer;
    }
  fclose($fp);
}

//Party_Start-------------------------------------------------------------------

$content_party_Start='POST /Party_Control HTTP/1.1
HOST: '.$address.':'.$port.'
SOAPACTION: "urn:schemas-sony-com:service:Party:1#X_Start"
CONTENT-TYPE: text/xml; charset="utf-8"
Connection: close
Content-Length: 505

<?xml version="1.0" encoding="utf-8"?>
  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
      <u:X_Start xmlns:u="urn:schemas-sony-com:service:Party:1">
        <PartyMode>PARTY</PartyMode>
        <ListenerList>uuid:5f9ec1b3-ed59-1900-4530-0007f5250a08</ListenerList>
      </u:X_Start>
    </s:Body>
  </s:Envelope>';

//Party_Start Senden------------------------------------------------------------

$fp = fsockopen ($address, $port);

fputs ($fp, $content_party_Start);

$inhalt = fgets($fp, 4096);

	$handle = fopen ("Party_Start.xml", "w");
	fwrite ($handle, $inhalt);
	fclose ($handle);

	$xml = simplexml_load_file("Party_Start.xml");

	$ret = $xml->SingerSessionID[0];

SetValueString(23791, $ret);

fclose($fp);




//Party_Entry-------------------------------------------------------------------

$content_party='POST /Party_Control HTTP/1.1
HOST: '.$address.':'.$port.'
Content-Length: 514
CONTENT-TYPE: text/xml; charset="utf-8"
SOAPACTION: "urn:schemas-sony-com:service:Party:1#X_Entry"
Connection: close

<?xml version="1.0" encoding="utf-8"?>
  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
      <u:X_Entry xmlns:u="urn:schemas-sony-com:service:Party:1">
        <SingerSessionID>'.$SingerSessionID.'</SingerSessionID>
        <ListenerList>uuid:5f9ec1b3-ed59-1900-4530-0007f5250a08</ListenerList>
      </u:X_Entry>
    </s:Body>
  </s:Envelope>';

//Party-Senden-----------------------------------------------------------------

$fp = fsockopen ($address, $port);

fputs ($fp, $content_party);

if ($fp)
  {
  while (!feof($fp))
    {
    $buffer = fgets($fp, 4096);
    echo $buffer;
    }
  fclose($fp);
}


//Party_GetState------------------------------------------------------------------

$content='POST /Party_Control HTTP/1.1
HOST: 192.168.178.151:8080
SOAPACTION: "urn:schemas-sony-com:service:Party:1#X_GetState"
CONTENT-TYPE: text/xml; charset="utf-8"
Connection: close
Content-Length: 298

<?xml version="1.0" encoding="utf-8"?>
  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <s:Body>
      <u:X_GetState xmlns:u="urn:schemas-sony-com:service:Party:1"></u:X_GetState>
    </s:Body>
  </s:Envelope>';


//Party1-Senden-----------------------------------------------------------------

$fp = fsockopen ($address, $port);

fputs ($fp, $content);

if ($fp)
  {
  while (!feof($fp))
    {
    $buffer = fgets($fp, 4096);
    echo $buffer;
    }
  fclose($fp);
}

?>

Viele Grüsse

André

$buffer = fgets($fp, 4096);
    ....
$handle = fopen ("Party_State.xml", "w");
fputs ($handle, $buffer->asXML());

Das kann so nicht gehen. asXML() ist eine Methode des simplexmlelement Objekt. $buffer ist aber nur ein String. Also muss man erst das Objekt mit $buffer erstellen und dann asXML ausgeben. Siehe http://php.net/manual/en/simplexmlelement.asxml.php
Tommi

… hmmm stimmt. Danke Tommi. Würde dann wohl so ähnlich aussehen:

$fp = fsockopen ($address, $port);

fputs ($fp, $content_party_GetState);

if ($fp)
{
   while (!feof($fp))
   {
   $buffer = fgets($fp, 4096);
    	
   echo $buffer;

   $xml = new SimpleXMLElement($buffer);

   $ret = $xml->SingerSessionID[0];

   SetValueString(23791, $ret);
   }
}

fclose($fp);

Beim Testen hat es nicht funktioniert, da der Teil des String mit der SessionID nicht erreicht wird.

Momentan bin ich bei der Fehlersuche und grüble vor allem, warum die Datei leer bleibt. Ursache ist offenbar, das fgets() nur 1 Zeile liest, das gesamte Packet somit nicht geschrieben (nur Zeile für Zeile überschrieben) wird.

$fp = fsockopen ($address, $port);

fputs ($fp, $content_party_GetState);

if ($fp)
{
  	while (!feof($fp))
    	{
		$buffer = fgets($fp, 4096);
		echo $buffer;

		$handle = fopen("Party_State.txt", "c");
		fwrite($handle, $buffer);
		fclose($handle);
		}
}

fclose($fp);

Ich glaube ich habe mich verrannt … :confused:

Irgendwie muss ich doch einen durch einen Header markierten Rückgabewert als Variable ablegen können.

Hat jemand einen anderen Ansatz ?

Viele Grüsse

André

Dann muss man die Schleife auch richtig abarbeiten. evtl. ist file_get_content auf die URL einfacher.


$fp = fsockopen ($address, $port);

fputs ($fp, $content_party_GetState);

if ($fp)
{
        $buffer='';
  	while (!feof($fp))
    	{
		$buffer .= fgets($fp, 4096);
        }
        fclose($fp);
	echo $buffer;

	$handle = fopen("Party_State.txt", "c");
	fwrite($handle, $buffer);
	fclose($handle);
	
}


… habs ! (Zumindest das Auslesen)

stream_get_contents() liefert den gesamten Inhalt für die Datei bzw. Buffer.

$fp = fsockopen ($address, $port);

fputs ($fp, $content_party_GetState);

		$buffer = stream_get_contents($fp);

		$handle = fopen("Party_State.txt", "c");
		fwrite($handle, $buffer);
		fclose($handle);
		
		//echo $buffer;
	
fclose($fp);

Jetzt muss ich „nur“ noch die Daten extrahieren. Leider ist die Rückgabe kein reines XML.

VG André