php simplexml_load_file with a dash ( - ) - php
Hi I'm struggling to get data from an xml file in php...
the xml file is here: http://musicbrainz.org/ws/2/artist/8bfac288-ccc5-448d-9573-c33ea2aa5c30?inc=release-groups
and so far after loading it into simplexml_load_file as $xml
I want to do something like this:
<?php
$url = "http://musicbrainz.org/ws/2/artist/8bfac288-ccc5-448d-9573-c33ea2aa5c30?inc=release-groups";
$xml = simplexml_load_file($url);
$releasegrouplist = "release-group-list";
$releasegroup = "release-group";
$i = "0";
for ($i = 0; $i <= 30; $i++)
{
echo "release: " . $xml->artist->$releasegrouplist->$releasegroup[$i]->title;}
The problem arises when I try to use it in a for loop with an $i variable as shown above.
Any tips or easier ways to do this?
Thanks everyone
Try this syntax instead. This script works for me with the change below (PHP 5.3.6).
echo "release: " . $xml->artist->{'release-group-list'}->{'release-group'}[$i]->title;
Source
You haven't actually told us what the problem is, but I'm guessing it's that you haven't read the SimpleXML section in the PHP manual, where it says
Accessing elements within an XML document that contain characters not
permitted under PHP's naming convention (e.g. the hyphen) can be
accomplished by encapsulating the element name within braces and the
apostrophe.
Related
How to get variables from a different PHP file without executing the code?
I am trying to loop through all the php files listed in an array called $articleContents and extract the variables $articleTitle and $heroImage from each. So far I have the following code: $articleContents = array("article1.php", "article2.php"); // array of all file names $articleInfo = []; $size = count($articleContents); for ($x = 0; $x <= $size; $x++) { ob_start(); if (require_once('../articles/'.$articleContents[$x])) { ob_end_clean(); $entry = array($articleContents[$x],$articleTitle,$heroImage); array_push($articlesInfo, $entry); } The problem is, the php files visited in the loop have html, and I can't keep it from executing. I would like to get variables from each of these files without executing the html inside each one. Also, the variables $articleTitle and $heroImage also exist at the top of the php file I'm working in, so I need to make sure the script knows I'm calling the variables in the external file and not the current one. If this is not possible, can you please recommend an alternative method? Thanks!
Don't do this. Your PHP scripts should be for your application, not for your data. For your data, if you want to keep it file-based, use a separate file. There are plenty of formats to choose from. JSON is quite popular. You can use PHP's built-in serialization as well, which has support for more PHP-native types but is not as portable to other frameworks.
A little hacky but seems to works: $result = eval( 'return (function() {?>' . file_get_contents('your_article.php') . 'return [\'articleTitle\' => $articleTitle, \'heroImage\' => $heroImage];})();' ); Where your_article.php is something like: <?php $articleTitle = 'hola'; $heroImage = 'como te va'; The values are returned in the $result array. Explanation: Build a string of php code where the code in your article scripts are wrapped inside a function that returns an array with the values you want. function() { //code of your article.php return ['articleTitle' => $articleTitle, 'heroImage' => $heroImage]; } Maybe you must do some adaptations to the strings due <?php ?> tags placements. Anyway, this stuff is ugly. I'm very sure that it can be refactored in some way.
Your problem (probably) comes down to using parentheses with require. See the example and note here. Instead, format your code like this $articlesInfo = []; // watch your spelling here foreach ($articleContents as $file) { ob_start(); if (require '../articles/' . $file) { // note, no parentheses around the path $articlesInfo[] = [ $file, $articleTitle, $heroImage ]; } ob_end_clean(); } Update: I've tested this and it works just fine.
XML tagname is a PHP function
I'm trying to parse an XML file in PHP with the simplexml_load_file function. Everything is fine, except my XML file has a <TIME> tag, which is a PHP function. So the following code fails to get the tag value : $xml = simplexml_load_file('some_xml_file.xml'); $value = $xml->SOME_TAG->TIME; How do I get this value?
From the PHP manual: Accessing elements within an XML document that contain characters not permitted under PHP's naming convention (e.g. the hyphen) can be accomplished by encapsulating the element name within braces and the apostrophe. Example #3 Getting <?php include 'example.php'; $xml = new SimpleXMLElement($xmlstr); echo $xml->movie->{'great-lines'}->line; // "PHP solves all my web problems" ?> And if you need to get an attribute you can do this: So far, we have only covered the work of reading element names and their values. SimpleXML can also access element attributes. Access attributes of an element just as you would elements of an array. foreach ($xml->movie[0]->rating as $rating) { switch((string) $rating['type'])
This works for me <?php $xmlString = "<top><middle><TIME>1:27</TIME></middle></top>"; $xml = simplexml_load_string($xmlString); echo $xml->middle->TIME; php /tmp/xml.php 1:27
Check the contents of your XML file. For your PHP code to work, it should AT LEAST contain this: <XML> <SOME_TAG> <TIME>1:27</TIME> </SOME_TAG> </XML> When I use this XML file combined with your code, it works as expected.
Thanks everyone, I manage to get the value but there's still something strange. XML example : <INGREDIENTS> <INGREDIENT> <NAME>Potatoes</NAME> <AMOUNT>10 kg</AMOUNT> <TME>20 min</TIME> </INGREDIENT> </INGREDIENTS> PHP code to get NAME, AMOUNT and TIME values : $ing = $xml->INGREDIENTS->INGREDIENT; $name = $ing->NAME; $amount= $ing->AMOUNT; $time= $ing->TIME; echo $name." / ".$amount." / ".$time; Result : Potatoes / 10 kg / However, if I use the whole path to the TIME tag : $ing = $xml->INGREDIENTS->INGREDIENT; $name = $ing->NAME; $amount= $ing->AMOUNT; $time= $xml->INGREDIENTS->INGREDIENT->TIME; echo $name." / ".$amount." / ".$time; Result : Potatoes / 10 kg / 20 min Can anyone explain why it's working this way ?
Line Break in PHP for-loop
There have been a bunch of questions like this already, but none of the answers seem to help me. I would like to have a line-break after each output from a loop. I am using double-quoted strings, like I read here, as well as using HTML (because I want the browser to recognize the line-breaks too) as I read here. It does create a line-break, however only below the complete output. I cannot manage to create a line-break between the outputs of the loop. Basically I get a block of text and then a linebreak. Here is the loop I am using: <?php include_once('simple_html_dom.php'); $target_url = "http://www.buzzfeed.com/trending?country=en-us"; $html = new simple_html_dom(); $html->load_file($target_url); $posts = $html->find('ul[class=list--numbered trending-posts trending-posts- now]'); $limit = 10; $limit = count($posts) < $limit ? count($posts) : $limit; for($i=0; $i < $limit; $i++){ $post = $posts[$i]; $post->find('div[class=trending-post-text]',0)->outertext = ""; echo strip_tags($post, '<p><a>') . "<br/>\n"; } I've also tried "\r\n" and a bunch of variations, as well as the nl2br() function. I believe the PHP_EOL command is meant only for the command line, from what I've researched. I'm an absolute beginner with PHP, so I am probably missing something simple, but I can't figure it out. EDIT: Here is what it prints: http://globalsocialnews.com/crawler/test8.php I also included the complete code in case that helps.
You can do line break using css implementation ... like: .rcorners1 a { display: block; margin-bottom: 10px;//for show extra margin between each line... } Edit: Use margin css attribute for extra margin... please try implementing this...
Better Use echo "</br>";
Breaking foreach at certain string/ Reading through text file and generating XML
I don't know if this is the right way to go about it, but right now I am dealing with a very large text file of membership details. It is really inconsistent though, but typically conforming to this format: Name School Department Address Phone Email &&^ (indicating the end of the individual record) What I want to do with this information is read through it, and then format it into XML. So right now I have a foreach reading through the long file like this: <?php $textline = file("asrlist.txt"); foreach($textline as $showline){ echo $showline . "<br>"; } ?> And that's where I don't know how to continue. Can anybody give me some hints on how I could organize these records into XML?
Here a straightforward solution using simplexml: $members = explode('&&^', $textline); // building array $members $xml = new SimpleXMLElement("<?xml version="1.0" encoding="UTF-8"?><members></members>"); $fieldnames = array('name','school','department','address','phone','email'); // set $fieldsep to character(s) that seperate fields from each other in your textfile $fieldsep = '\p\n'; // a wild guess... foreach ($members as $member) { $m = explode($fieldsep, $member); // build array $m; $m[0] would contain "name" etc. $xmlmember = $xml->addChild('member'); foreach ($m as $key => $data) $xmlmember->addChild($fieldnames[$key],$data); } // foreach $members $xml->asXML('mymembers.xml'); For reading and parsing the text-file, CSV-related functions could be a good alternative, as mentioned by other users.
To read big files you can use fgetcsv
If && works as a delimiter for records in that file, you could start with replacing it with </member><member>. Prepend whole file with <member> and append </member> at the end. You will have something XML alike. How to replace? You might find unix tools like sed useful. sed 's/&&/\<\/member\>\<member\>/' <input.txt >output.xml You can also accomplish it with PHP, using str_replace(): foreach($textline as $showline){ echo str_replace( '&&', '</member><member>', $showline ) . "<br>"; }
Parsing XML with PHP (simplexml)
Firstly, may I point out that I am a newcomer to all things PHP so apologies if anything here is unclear and I'm afraid the more layman the response the better. I've been having real trouble parsing an xml file in to php to then populate an HTML table for my website. At the moment, I have been able to get the full xml feed in to a string which I can then echo and view and all seems well. I then thought I would be able to use simplexml to pick out specific elements and print their content but have been unable to do this. The xml feed will be constantly changing (structure remaining the same) and is in compressed format. From various sources I've identified the following commands to get my feed in to the right format within a string although I am still unable to print specific elements. I've tried every combination without any luck and suspect I may be barking up the wrong tree. Could someone please point me in the right direction?! $file = fopen("compress.zlib://$url", 'r'); $xmlstr = file_get_contents($url); $xml = new SimpleXMLElement($url,null,true); foreach($xml as $name) { echo "{$name->awCat}\r\n"; } Many, many thanks in advance, Chris PS The actual feed
Since no one followed my closevote, I think I can just as well put my own comments as an answer: First of all, SimpleXml can load URIs directly and it can do so with stream wrappers, so your three calls in the beginning can be shortened to (note that you are not using $file at all) $merchantProductFeed = new SimpleXMLElement("compress.zlib://$url", null, TRUE); To get the values you can either use the implicit SimpleXml API and drill down to the wanted elements (like shown multiple times elsewhere on the site): foreach ($merchantProductFeed->merchant->prod as $prod) { echo $prod->cat->awCat , PHP_EOL; } or you can use an XPath query to get at the wanted elements directly $xml = new SimpleXMLElement("compress.zlib://$url", null, TRUE); foreach ($xml->xpath('/merchantProductFeed/merchant/prod/cat/awCat') as $awCat) { echo $awCat, PHP_EOL; } Live Demo Note that fetching all $awCat elements from the source XML is rather pointless though, because all of them have "Bodycare & Fitness" for value. Of course you can also mix XPath and the implict API and just fetch the prod elements and then drill down to the various children of them. Using XPath should be somewhat faster than iterating over the SimpleXmlElement object graph. Though it should be noted that the difference is in an neglectable area (read 0.000x vs 0.000y) for your feed. Still, if you plan to do more XML work, it pays off to familiarize yourself with XPath, because it's quite powerful. Think of it as SQL for XML. For additional examples see A simple program to CRUD node and node values of xml file and PHP Manual - SimpleXml Basic Examples
Try this... $url = "http://datafeed.api.productserve.com/datafeed/download/apikey/58bc4442611e03a13eca07d83607f851/cid/97,98,142,144,146,129,595,539,147,149,613,626,135,163,168,159,169,161,167,170,137,171,548,174,183,178,179,175,172,623,139,614,189,194,141,205,198,206,203,208,199,204,201,61,62,72,73,71,74,75,76,77,78,79,63,80,82,64,83,84,85,65,86,87,88,90,89,91,67,92,94,33,54,53,57,58,52,603,60,56,66,128,130,133,212,207,209,210,211,68,69,213,216,217,218,219,220,221,223,70,224,225,226,227,228,229,4,5,10,11,537,13,19,15,14,18,6,551,20,21,22,23,24,25,26,7,30,29,32,619,34,8,35,618,40,38,42,43,9,45,46,651,47,49,50,634,230,231,538,235,550,240,239,241,556,245,244,242,521,576,575,577,579,281,283,554,285,555,303,304,286,282,287,288,173,193,637,639,640,642,643,644,641,650,177,379,648,181,645,384,387,646,598,611,391,393,647,395,631,602,570,600,405,187,411,412,413,414,415,416,649,418,419,420,99,100,101,107,110,111,113,114,115,116,118,121,122,127,581,624,123,594,125,421,604,599,422,530,434,532,428,474,475,476,477,423,608,437,438,440,441,442,444,446,447,607,424,451,448,453,449,452,450,425,455,457,459,460,456,458,426,616,463,464,465,466,467,427,625,597,473,469,617,470,429,430,615,483,484,485,487,488,529,596,431,432,489,490,361,633,362,366,367,368,371,369,363,372,373,374,377,375,536,535,364,378,380,381,365,383,385,386,390,392,394,396,397,399,402,404,406,407,540,542,544,546,547,246,558,247,252,559,255,248,256,265,259,632,260,261,262,557,249,266,267,268,269,612,251,277,250,272,270,271,273,561,560,347,348,354,350,352,349,355,356,357,358,359,360,586,590,592,588,591,589,328,629,330,338,493,635,495,507,563,564,567,569,568/mid/2891/columns/merchant_id,merchant_name,aw_product_id,merchant_product_id,product_name,description,category_id,category_name,merchant_category,aw_deep_link,aw_image_url,search_price,delivery_cost,merchant_deep_link,merchant_image_url/format/xml/compression/gzip/"; $zd = gzopen($url, "r"); $data = gzread($zd, 1000000); gzclose($zd); if ($data !== false) { $xml = simplexml_load_string($data); foreach ($xml->merchant->prod as $pr) { echo $pr->cat->awCat . "<br>"; } }
<?php $xmlstr = file_get_contents("compress.zlib://$url"); $xml = simplexml_load_string($xmlstr); // you can transverse the xml tree however you want foreach ($xml->merchant->prod as $line) { // $line->cat->awCat -> you can use this } more information here
Use print_r($xml) to see the structure of the parsed XML feed. Then it becomes obvious how you would traverse it: foreach ($xml->merchant->prod as $prod) { print $prod->pId; print $prod->text->name; print $prod->cat->awCat; # <-- which is what you wanted print $prod->price->buynow; }
$url = 'you url here'; $f = gzopen ($url, 'r'); $xml = new SimpleXMLElement (fread ($f, 1000000)); foreach($xml->xpath ('//prod') as $name) { echo (string) $name->cat->awCatId, "\r\n"; }