So I'm using curl to call a php page to receive an XML response. simplexml_load_string isn't liking my xml for some reason. Using libxml_get_errors() I was able to get the title error message.
Here's code:
$service_url = 'blahblahblah';
$curl = curl_init($service_url);
$curl_post_data = array(
"action" => "LISTWORKOUT",
"accesstoken" => $accesstoken,
"workoutid" => 2,
);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
$curl_response = curl_exec($curl);
curl_close($curl);
libxml_use_internal_errors(true);
$xml=simplexml_load_string($curl_response); //or simplexml_load_file
foreach( libxml_get_errors() as $error ) {
print_r($error);
}
echo $curl_response;
Heres the page its hitting:
$workoutid = mysql_real_escape_string($_POST['workoutid']);
// Create the Element and Append the Child
$result = mysql_query("SELECT * FROM `lifts` WHERE `workoutid` = $workoutid OR `sharedid` = $workoutid ",$sqlAPI);
$xml = new DOMDocument("1.0");
$xml->formatOutput=true;
$workout=$xml->createElement("workout");
$xml->appendChild($workout);
while($row = mysql_fetch_array($result))
{
$lift=$xml->createElement("lift");
$workout->appendChild($lift);
$name=$xml->createElement("name",$row['name']);
$lift->appendChild($name);
$weight=$xml->createElement("weight", $row['weight']);
$lift->appendChild($weight);
$sets=$xml->createElement("sets",$row['sets']);
$lift->appendChild($sets);
$reps=$xml->createElement("reps", $row['reps']);
$lift->appendChild($reps);
}
echo"<xmp>" . $xml->saveXML() . "</xmp>";
And for good measure here is the output:
LibXMLError Object ( [level] => 3 [code] => 64 [column] => 11 [message] =>
XML declaration allowed only at the start of the document [file] => [line] => 1 )
<?xml version="1.0"?>
<workout>
<lift>
<name>Squats</name>
<weight>45</weight>
<sets>5</sets>
<reps>5</reps>
</lift>
<lift>
<name>Overhead Press</name>
<weight>45</weight>
<sets>5</sets>
<reps>5</reps>
</lift>
<lift>
<name>Deadlift</name>
<weight>45</weight>
<sets>1</sets>
<reps>5</reps>
</lift>
</workout>
Note the echo displays the XML with no issues.
I think it has something to do with these quotation marks maybe? It might be a stretch. I already went ahead and tried str_replace them but still no bueno.
From the image and code in the question is seems like what you have in your document is this:
<xmp>
<?xml version="1.0"?>
<workout>
That is, the root element of the document you’re feeding to simplexml_load_string
is <xmp>
, not <workout>
. So LibXML starts parsing that document from the <xmp>
element, then hits the <?xml version="1.0"?>
and says, Hey that’s an XML declaration—that shouldn’t be here.
To prevent the XML declaration from getting added, you can replace your $xml->saveXML()
with:
foreach ($xml->childNodes as $node) {
echo $xml->saveXML($node);
}
Or see some of the other answers for the questions PHP DomDocument output without <?xml version="1.0" encoding="UTF-8"?> and remove xml version tag when a xml is created in php.
The idea is just that instead of outputting the whole thing as a document, your code instead iterates through all nodes of the document starting with the root and outputs them one-by-one in order.
So because you’re outputting individual nodes that way instead of the whole document as a document, that skips the unwanted XML declaration at the beginning for the document.
An alternative that may also work is, make saveXML(…)
only emit the document element (root):
$xml->saveXML($xml->documentElement)
If it works, it’ll emit your workout
element and all its descendants, skipping the XML declaration.