How to fix XML parsing error with PHP? [duplicate] - php

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
PHP library for parsing XML with a colons in tag names?
I have the xml shown below and I want to parse out the product title. When I use the php code below, I get "Parse error: syntax error, unexpected ':' in /home/content/c/a/s/cashme/html/buylooper/xml.php on line 5" because of the ":" located in the tag. How do I resolve this?
*update: I've got the answer to the first part, but am having trouble in how to parse out an attribute of an xml tag. The tag I am having trouble with is the "s:image" tag (link attribute) inside the "s:images" tag.
<?php
$url = 'xml-file.xml';
$xml = simplexml_load_file($url);
$title = $xml->entry[0]->s:product->s:title;
//print
echo '<br/>';
echo $title;
?>
<entry gd:kind="shopping#product">
<s:product>
<s:googleId>9400569674928563633</s:googleId>
<s:author>
<s:name>Amazon.com</s:name>
<s:accountId>2860562</s:accountId>
</s:author>
<s:creationTime>2010-08-19T05:50:21.000Z</s:creationTime>
<s:modificationTime>2012-01-26T23:54:26.000Z</s:modificationTime>
<s:country>US</s:country>
<s:language>en</s:language>
<s:title>Canon powershot s95 10 mp digital camera with 3.8x wide angle optical image stabilized zoom and 3.0-inch lcd</s:title>
<s:description>desc</s:description>
<s:link>http://www.amazon.com/Canon-PowerShot-S95-Stabilized-3-0-Inch/dp/B003ZSHNGS</s:link>
<s:brand>Canon</s:brand>
<s:condition>new</s:condition>
<s:gtin>00013803126556</s:gtin>
<s:gtins>
<s:gtin>00013803126556</s:gtin>
</s:gtins>
<s:inventories>
<s:inventory channel="online" availability="inStock">
<s:price shipping="0.0" currency="USD">340.41</s:price>
</s:inventory>
</s:inventories>
<s:images>
<s:image link="http://ecx.images-amazon.com/images/I/519z3AjKzHL._SL500_AA300_.jpg"/>
</s:images>
</s:product>
</entry>

Parse the namespaces first.
$namespaces = $xml->getNameSpaces(true);
$s = $xml->children($namespaces['s']);
echo (string)$s->product->title. "\n";
echo (string)$s->product->images->image->attributes()->link;

You need to get the correct namespace with . This is untested, but might do the trick:
$url = 'xml-file.xml';
$xml = simplexml_load_file($url);
$namespaces = $xml->entry->getNameSpaces(true);
// Get children of the correct namespace
$s = $xml->entry[0]->children($namespaces['s']);
$title = $s->product->title;
//print
echo '<br/>';
echo $title;

Related

parse and process HTML/XML/plain text page [duplicate]

This question already has answers here:
How do you parse and process HTML/XML in PHP?
(31 answers)
Closed 3 years ago.
I am creating a small php app that pulls data from a remote website its working great but i would like to make it more user friendly now.
I need to get a few specific items from the page and as far as I can tell the page looks like an xml file wen you look at sorce code but it has no style to it and appears as plain text so I don't really know what to do.
The page I am trying to get looks like this
<channel>
<name>data</name>
<id>data</id>
<img>data</img>
<auther>data</auther>
<mp3>data</mp3>
<bio>data</bio>
</channel>
<channel>
<name>data</name>
<id>data</id>
<img>data</img>
<auther>data</auther>
<mp3>data</mp3>
<bio>data</bio>
</channel>
<channel>
<name>data</name>
<id>data</id>
<img>data</img>
<auther>data</auther>
<mp3>data</mp3>
<bio>data</bio>
</channel>
<channel>
<name>data</name>
<id>data</id>
<img>data</img>
<auther>data</auther>
<mp3>data</mp3>
<bio>data</bio>
</channel>
I need to get all the data from each tag under the channel tag and keep it in the same order to echo it back out onto my own page in the same way.
How could i do this ? i tried using regex with the following patter
$pattern = '<channel>
<name>(.*)</name>
<id>(.*)</id>
<img>(.*)</img>
<auther>(.*)</auther>
<mp3>(.*)</mp3>
<bio>(.*)</bio>
</channel>';
but that doesn't work I really need the best and simplest way to do this.
$SimpleXMLElement = new SimpleXMLElement($str);
foreach ($SimpleXMLElement->children() as $Channel) {
foreach ($Channel->children() as $Child) {
echo $Child->getName() . ' = ' . (string) $Child;
}
}
this way you can use SimpleXMLElement, it's very easy
I would "sanitize" the incoming data and make an xml document out of it. This can be done by simply wrapping it into a surrounding tag. (I name it channels). Having this, you can parse the data using DOM:
// Sanitize input data. Make an xml out of it
$xml = '<channels>';
$xml .= file_get_contents($url);
$xml .= '</channels>';
// Create a document
$doc = new DOMDocument();
$doc->loadXML($xml);
// Iterate through channel elements
foreach($doc->getElementsByTagName('channel') as $channel) {
echo $channel->getElementsByTagName('name')->item(0)->nodeValue . PHP_EOL;
echo $channel->getElementsByTagName('id')->item(0)->nodeValue . PHP_EOL;
// And so on ...
}

PHP - String could not be parsed as XML [duplicate]

This question already has answers here:
Reference - What does this error mean in PHP?
(38 answers)
Closed 8 years ago.
I am currently using the following code, but no result is returned:
<?php
$url = 'http://myknowledge.org.uk/xml';
$xml = new SimpleXMLElement(file_get_contents($url));
foreach ($xml->item as $item) {
$title = $item->title;
}
echo $title;
?>
The XML Code:
<?xml version="1.0" encoding="utf-8"?>
<item>
<title>Apple</title>
<notableFor>Fruit</notableFor>
<wikiid>Apple</wikiid>
<description>The apple is the pomaceous fruit of the apple tree, Malus domestica of the rose family. It is one of the most widely cultivated tree fruits, and the most widely known of the many members of genus Malus that are used by humans.</description>
<img></img>
<website></website>
<translate>
<de>Äpfel</de>
<fr>pomme</fr>
<it>mela</it>
<es>manzana</es>
<ru>яблоко</ru>
</translate>
<nutritionalInfomation name="Apple" quantity="100g">
<calories>52</calories>
<carb>14</carb>
<fibre>2.4</fibre>
<protein>0.3</protein>
<fat>0.2</fat>
</nutritionalInfomation>
</item>
If anybody has an idea how to fix this I would love to know. Thanks.
The XML appears to be invalid in lines 4 and 5:
<notableFor>Fruit</title>
<wikiid>Apple</title>
Which should be:
<notableFor>Fruit</notableFor>
<wikiid>Apple</wikiid>
I recommend using the XML validator at http://www.w3schools.com/xml/xml_validator.asp to debug errors with your XML code.
Also, as your root element is item, you may want to change your PHP code:
<?php
$url = 'http://myknowledge.org.uk/xml';
$item = new SimpleXMLElement(file_get_contents($url));
$title = $item->title;
$description = $item->description;
?>
(I don't have a copy of PHP on hand to test this, but according to http://php.net/manual/en/simplexml.examples-basic.php, this should work)
Xml can have only 1 root element, in your example the root is item
When loading to SimpleXML you can get the root name with $xml->getName()
$url = 'http://myknowledge.org.uk/xml';
$item = new SimpleXMLElement($url, null, true);
$title = $item->title;
$description = $item->description;
Or you should enclose you items in another root i.e items if you need multiple

parsing xml file in php [duplicate]

This question already has answers here:
How do you parse and process HTML/XML in PHP?
(31 answers)
Closed 9 years ago.
I have an xml file which consist of name of the country and its code.
<country>
<name>ALBANIA</name>
<code>AL</code>
</country>
<country>
<name>ALGERIA</name>
<code>DZ</code>
</country>
<country>
<name>AMERICAN SAMOA</name>
<code>AS</code>
</country>
now I am using following php code to store them in array and printing them(country.xml file is in the same folder as this php code.
$countries = array();
$file = new SimpleXMLElement(__DIR__ . '/country.xml', null, true);
foreach ($file->country as $country) {
$name = trim($country['name']);
$code = trim(strtoupper($country['code']));
$countries[$code] = $name;
echo $code;
}
but this php code shows blank page. Can anyone guide me where I am making mistake and help me to correct it or give some better method to parse xml file.
The simplexml_load_file() in PHP will do the job.
<?php
$xml = simplexml_load_file('country.xml');
$i=0;
$countryName=array();
$countryCode=array();
foreach($xml as $k=>$v)
{
$countryName[$i] = (string) $xml->country[$i]->name;
$countryCode[$i] = (string) $xml->country[$i]->code;
$i++;
}
print_r($countryName);
print_r($countryCode);
?>

Linked in xml response to php variables [duplicate]

This question already has answers here:
How do you parse and process HTML/XML in PHP?
(31 answers)
Closed 9 years ago.
i am getting this result from my linked in connect script,
<person>
<email-address>xzenia1#gmail.com</email-address>
<picture-url>http://m3.licdn.com/mpr/mprx/0_UiHHf6SiF4yuBerHUkfUfkshFpomUIrHMbpBf5Iy4sOYk7FecL4XTLxtdAEl42AXsho9hGzDtRBl</picture-url>
</person>
this is the php call
$xml_response = $linkedin->getProfile("~:(email-address,picture-url)");
how to make them assign to separate PHP variable.
You can load your xml as string with simplexml_load_string and then loop in it to get all data
$xml = simplexml_load_string($xml_response);
foreach($xml as $key => $val)
{
echo "$key=>$val<br>" . "\n";
}
This will output
email-address=>xzenia1#gmail.com
picture-url=>http://m3.licdn.com/mpr/mprx/0_UiHHf6SiF4yuBerHUkfUfkshFpomUIrHMbpBf5Iy4sOYk7FecL4XTLxtdAEl42AXsho9hGzDtRBl
Live sample
Try,
$xml = (array)simplexml_load_string($xml_response);
echo $email=$xml['email-address'];
echo $picture=$xml['picture-url'];
$xml = simplexml_load_string($linkedin->getProfile("~:(email-address,picture-url)"));
echo $xml->{'email-address'}[0] . "<br />";
echo $xml->{'picture-url'}[0];
simplexmldoesn't like - in node names, therefore use $xml->{'email-address'} instead of $xml->email-address.
use index [0] on both nodes, just in case, if one day your simplexml object would contain more than one <person> node...
see it working: http://codepad.viper-7.com/dQQ6sa

Parsing WordPress XML, slash:comments syntax?

This is really just a syntax question.
I have a PHP script that parses my WordPress feed and returns the latest posts. I also want my script to parse the # of comments, but the WordPress feed XML object for number of comments has a colon in it (slash:comments). It causes the following error:
Parse error: syntax error, unexpected
':' in ... on line ...
I have tried each of the following without luck:
$xml->slash:comments
$comments = 'slash:comments'
$xml->$comments
$xml->slash.':'.comments
$xml->{slash:comments}
$xml->{'slash:comments'}
How do I parse an object with a colon?
Alternatively, you can use xpath() to access the nodes. Given the following as an xml string:
<entry>
<id>http://gdata.youtube.com/feeds/api/videos/xyz12345678</id>
<published>2007-01-17T23:41:00.000Z</published>
<updated>2010-11-14T03:52:25.000Z</updated>
<yt:location>Mount Washington Observatory, NH</yt:location>
<media:group>
<media:title type='plain'>Example of a Title</media:title>
<media:duration seconds='126'/>
</media:group>
</entry>
You could do this:
$xml = simplexml_load_string(*xmlstring_from_above*);
$location = $xml->xpath('yt:location');
echo($location[0]); // output: "Mount Washington Observatory, NH"
$title = $xml->xpath('media:group/media:title');
echo($title[0]); // output: "Example of a Title"
$duration = $xml->xpath('media:group/media:duration');
echo($duration[0]['seconds']); // output: "126"
As you can see, to get the nodes with colons, you may use xpath() with a relative path to the node.
A variable in PHP can never have a colon in it. Therefore, you should check your XML parser to see how it handles colons.
$string = file_get_contents("http://domain.tld/?feed=rss2");
$string = str_replace('slash:comments','slashcomments',$string);
$xml = simplexml_load_string($string);
Use str_replace to remove the colons from the string and allow simplexml_load_string to function as normal.
For example:
$string = file_get_contents("http://domain.tld/?feed=rss2");
$string = str_replace('slash:comments','slashcomments',$string);
$xml = simplexml_load_string($string);
foreach ($xml->channel->item as $val) {
echo $val->pubDate.'<br />';
echo $val->title.'<br />';
echo $val->slashcomments.'<br /><br />';
}
... should return the published date, title, and number of comments of the posts listed in a WordPress feed. My code is more advanced, but this illustrates the workaround.
Thank you, Arda Xi, for your help!

Categories