I have a array which it reads its cells from a xml file,i wrote it by "for" but now because i don't know how many node i have i wanna to write this loop in a way that it start and finish up to end of xml file.my code with for is:
$description=array();
for($i=0;$i<2;$i++)
{
$description[$i]=read_xml_node("dscription",$i);
}
and my xml file:
<eth0>
<description>WAN</description>
</eth0>
<eth1>
<description>LAN</description>
</eth1>
in this code i must know "2",but i wanna to know a way that doesn't need to know "2".
i am not sure what kind of parser you are using, but it is very easy with simplexml, so i put together some sample code using simplexml.
something like this should do the trick:
$xmlstr = <<<XML
<?xml version='1.0' standalone='yes'?>
<node>
<eth0>
<description>WAN</description>
</eth0>
<eth1>
<description>LAN</description>
</eth1>
</node>
XML;
$xml = new SimpleXMLElement($xmlstr);
foreach ($xml as $xmlnode) {
foreach ($xmlnode as $description) {
echo $description . " ";
}
}
output:
WAN LAN
$length = count($description);
for ($i = 0; $i < $length; $i++) {
print $description[$i];
}
The parser you use might allow you to use a while loop which will return false when it has reached the end of the XML document. For example:
while ($node = $xml->read_next_node($mydoc)) {
//Do whatever...
}
If none exists, you can try using count() as the second parameter of your for loop. It returns the length of an array you specify. For example:
for ($i = 0; $i < count($myarray); $i++) {
//Do whatever...
}
Related
I load an XML file $xml=simplexml_load_file("productsXML.xml", 'SimpleXMLElement', LIBXML_NOCDATA);
Then i want to delete the items that have a price lower than 16
foreach($xml as $item) {
$item->suggested_price = $item->suggested_price / 1.24;
$timh = (int) $item->suggested_price;
if ($timh < 16) {
//deleting the specific $item
}
}
After that, i recreate the XML with new DOMDocument
I ve tried lots of solutions in the internet without success. I can manipulate the under-16 prices or print them, but i can't somehow delete the whole $item.
XML SAMPLE
<?xml version="1.0" encoding="UTF-8"?>
<products>
<product id="25">
<name><![CDATA[test]]></name>
<name_en><![CDATA[test_en]]></name_en>
<modified>2020-06-29T08:45:09+03:00</modified>
<suggested_price>84.5</suggested_price>
$doc = new DOMDocument;
$doc->load('YourFile.xml');
$thedocument = $doc->documentElement;
$thedocument->removeChild(YourItem);
Can you show the code which u try?
You can Edit the Price right? then you propably need to Remove Parent!?
You can use unset, and for each time you unset continue the loop without incrementing the counter for the index.
$xml = simplexml_load_file("productsXML.xml", 'SimpleXMLElement', LIBXML_NOCDATA);
$cnt = 0;
foreach ($xml as $item) {
$item->suggested_price = $item->suggested_price / 1.24;
if ((int) $item->suggested_price < 16) {
unset($xml->product[$cnt]);
continue;
}
$cnt++;
}
echo $xml->asXml();
here is part of my xml file
<?xml version="1.0" encoding="ISO-8859-1" ?>
<stati_team>
<team>
<team>Bayern Munich</team>
<victory>10</victory>
<loss>2</loss>
<ranking>1</ranking>
</team>
<team>
<team>RB Leipzig</team>
<victory>8</victory>
<loss>4</loss>
<ranking>2</ranking>
</team>
</stati_team>
my goal is to display the xml file as the browser does here is my php code he work without any problem
<?php
$file = "team.xml";
$depth = 0;
function startElement($parser, $name, $attrs){
global $depth;
$depth++;
print"<br>";
for ($i = 0; $i < $depth; $i++) {
print " ";
}
print "<<font color=\"#0000cc\">$name</font>\n";
print">";
}
function endElement($parser, $name){
global $depth;
$depth--;
for ($i=0; $i <$depth ; $i++) {
print " ";
}
print "<<font color=\"#0000cc\">/$name</font>";print "><br>";
}
function characterData($parser,$data){
global $depth;
for ($i = 0; $i < $depth; $i++) {
print " ";
}
print "$data";
}
$xml_parser=xml_parser_create();
xml_set_element_handler($xml_parser,"startElement","endElement");
xml_set_character_data_handler($xml_parser,"characterData");
if(!($fp=fopen($file,"r"))){
die("File XML: error");
}
while($data=fread($fp,4096)){
if(!xml_parse($xml_parser,$data,feof($fp))){
die("Error XML, ligne".xml_get_current_line_number($xml_parser)." !!!");
}
}
xml_parser_free($xml_parser);
?>
output
the output of the XML file is not bad. So my question is how we do so that the <team> tag is at the same level as </team> tag
I fear that you do not fully understand what the functions are doing. Try to look at my solution and the respective functions in the php manual and hopefully it will be a bit clearer. if not add a comment as I now know and understand these functions, I have never heard about before today.
Here is the solution: To show what it does i have used "+" and "*" instead of non breaking spaces.
The original had unfortunately a lot of problems i fixed now. One example were the spaces inside the tags.
I changed the following things:
removed the unnecessary stuff inside the characterdate function. This function is only thought to print out the content between the tags - you do not want any additional stuff here!
Then I added a new global var $lastaction which stores the type of the last tag (start or end).
And now comes the critical part that took you 9 hours:
If the last tag was an end tag we need to indent the tag for the number of levels. Thats it. So easy. But it also took me some time to get that super simple solution. :-/
I also added an if in the start tag to remove the break if the last tag was an end tag. because that looked wrong and not like your example.
I also replaced the gruesome for(echo) loops with str_repeat()
<?php
$file = "team.xml";
$depth = 0;
$lastaction="";
function startElement($parser, $name, $attrs){
global $depth,$lastaction;
$depth++;
if ($lastaction!="end") print"<br>";
echo str_repeat('++', $depth);
print "<<font color=\"#0000cc\">$name</font>>";
$lastaction="start";
}
function endElement($parser, $name){
global $depth, $lastaction;
if ($lastaction=="end") echo str_repeat('**',$depth);
$depth--;
print "<<font color=\"#0000cc\">/$name</font>><br>";
$lastaction ="end";
}
function characterData($parser,$data){
print $data;
}
$xml_parser=xml_parser_create();
xml_set_element_handler($xml_parser,"startElement","endElement");
xml_set_character_data_handler($xml_parser,"characterData");
if(!($fp=fopen($file,"r"))){
die("File XML: error");
}
while($data=fread($fp,4096)){
if(!xml_parse($xml_parser,$data,feof($fp))){
die("Error XML, ligne".xml_get_current_line_number($xml_parser)." !!!");
}
}
xml_parser_free($xml_parser);
?>
RESULT exactly as it should be
(the * and + are only for demonstration because they are added in two different functions so you should understand what is happening here - replace them by one or more non breaking spaces and your homework is finished. ;-)
+<STATI_TEAM>
++<TEAM>
+++<TEAM>Bayern Munich</TEAM>
+++<VICTORY>10</VICTORY>
+++<LOSS>2</LOSS>
+++<RANKING>1</RANKING>
**</TEAM>
++<TEAM>
+++<TEAM>RB Leipzig</TEAM>
+++<VICTORY>8</VICTORY>
+++<LOSS>4</LOSS>
+++<RANKING>2</RANKING>
**</TEAM>
*</STATI_TEAM>
I have never used XML before and am trying to loop through the XML and display all the display names in the 'A Team'. The code I am using is outputting 10 zeros and not the names.
The code I am using is attached below along with the feed.
Any assistance is much appreciated!
feed: https://apn.apcentiaservices.co.uk/ContactXML/agentfeed?organisation=se724de89ca150f
<?php
$url = 'https://apn.apcentiaservices.co.uk/ContactXML/agentfeed?organisation=se724de89ca150f';
$html = "";
$xml = simplexml_load_file($url);
for($i = 0; $i < 10; $i++){
$title = $xml->organisation['APN']->brand['AllStar Psychics']->pool['A Team']->agent[$i]->display-name;
echo $title;
}
echo $html;
?>
This might getthe basics you asked for. Not sure if it's what you want. I'm not that good at xpath.
$mydata = $xml->xpath('/organisation/brand/pool[#name="A Team"]//display-name');
foreach($mydata as $key=>$value){
echo('Name:' . $value .'<br>');
}
I need to read an XML file, i watched some tutorials and tried different sollutions, but for some reason I can't figure out why it doenst work.
The XML file that I want to read: http://www.voetbalzone.nl/rss/rss.xml
This is the code that im using:
$xml= "http://www.voetbalzone.nl/rss/rss.xml"
for ($i = 0; $i < 10; $i++)
{
$title = $xml->rss->channel->item[$i]->title;
}
The error I get: Premature end of data in tag
It works for me like this:
<?php
$xml = simplexml_load_file("http://www.voetbalzone.nl/rss/rss.xml");
for ($i = 0; $i < 10; $i++)
{
$title = $xml->channel->item[$i]->title;
}
?>
Note that you are overwriting the variable $title each time, so that you will have the title of the 10. element in it after the loop finished [I assume that is not what you want?]
To get all 'item'-Elements inside 'channel' as an Array to iterate through you can use xpath like this:
<?php
$xml = simplexml_load_file("http://www.voetbalzone.nl/rss/rss.xml");
$item_array = $xml->xpath("//rss/channel/item");
foreach($item_array as $item) {
echo $item->title . "\n";
}
?>
I would suggest to read about php's SimpleXML here: http://php.net/manual/en/book.simplexml.php
i have xml file $file.xml which includes the following
<?xml version="1.0"?>
<names><name>name1</name><name>name2</name><name>name3</name></names>
i need a way to check if <names> has more than one child <name> meaning that if the file has more than <name>name1</name> whick means that if <name>name2</name> or more exist to call a function.
i have tried the following
$file = "file.xml";
$result = file_get_contents($file);
if(#count(file($result)) > 1) {
//perform a function
}
the file_get_contents already gave me the values name1 name2 and name3
but the if(#count(file($result)) > 1) { did nothing
Thanks in advance
Yes its quite possible, you could use xpath in conjunction with this case:
$file = "file.xml";
$xml = simplexml_load_file($file);
$names = $xml->xpath('/names/name');
if(count($names) > 1) {
//perform a function
echo 'perform!';
}
Or an alternative with DOMDocument with xpath as well:
$dom = new DOMDocument();
$dom->load($file);
$count = $xpath->evaluate('count(/names/name)');
if($count > 1) {
echo 'perform!';
}