hey guys I'm trying to parse a xml(feeds) and save it with php?(I'm halfway),.i already achieve to load the xml and display just the data i need to display,.now how can i save the xml?
this is my code :
<?php
$html = "";
$url = "http://www.conciencia.net/rss.aspx";
$xml = simplexml_load_file($url);
$channel_title = $xml->channel->title;
$channel_link = $xml->channel->link;
$managingEditor = $xml->channel->managingEditor;
$channel_description = $xml->channel->description;
$lbd = $xml->channel->lastBuildDate;
$html .= "<br/>$channel_title";
$html .= "<br/>$channel_link";
$html .= "<br/>$managingEditor";
$html .= "<br/>$lbd";
$html .= "<br/>$channel_description<br/>";
for($i = 0; $i < 7; $i++){
$pubDate = $xml->channel->item[$i]->pubDate;
$title = $xml->channel->item[$i]->title;
$link = $xml->channel->item[$i]->link;
$guid = $xml->channel->item[$i]->guid;
$author = $xml->channel->item[$i]->author;
$description = $xml->channel->item[$i]->description;
$url0 = $xml->channel->item[$i]->enclosure->attributes()->url;
for($ii = 0; $ii < 2; $ii++){
$url = $xml->channel->item[$i]->enclosure[$ii]->attributes()->url;
}
$html .= "<br/>$pubDate";
$html .= "<a href='$link'><h3>$title</h3></a>";
$html .= "<br/>$guid";
$html .= "<br/>$author";
$html .= "<br/>$description";
$html .= "<br/>$url0";
$html .= "<br/>$url";
$html .= "<br/>$link<br/>";
}
echo $html;
?>
that code is working good, loading the tags from the xml i just want to display,
what i want to do after that is create a xml(as is below structured) and save the data.
how can i achieve that ?
myxml.xml
<channel>
<title>$channel_title</title>
<link>$channel_link</link>
<managingEditor>$managingEditor</managingEditor>
<channel_description>$channel_description</channel_description>
<item>
<title>$title</title>
<guid>$guid</guid>
<author>$author</author>
<description>$description</description>
<enclosure0>$url0</enclosure0>
<enclosure1>$url</enclosure>
</item>
<item>
<title>$title</title>
<guid>$guid</guid>
<author>$author</author>
<description>$description</description>
<enclosure0>$url0</enclosure0>
<enclosure1>$url</enclosure>
</item>
<item>
<title>$title</title>
<guid>$guid</guid>
<author>$author</author>
<description>$description</description>
<enclosure0>$url0</enclosure0>
<enclosure1>$url</enclosure>
</item>
<item>
<title>$title</title>
<guid>$guid</guid>
<author>$author</author>
<description>$description</description>
<enclosure0>$url0</enclosure0>
<enclosure1>$url</enclosure>
</item>
<item>
<title>$title</title>
<guid>$guid</guid>
<author>$author</author>
<description>$description</description>
<enclosure0>$url0</enclosure0>
<enclosure1>$url</enclosure>
</item>
<item>
<title>$title</title>
<guid>$guid</guid>
<author>$author</author>
<description>$description</description>
<enclosure0>$url0</enclosure0>
<enclosure1>$url</enclosure>
</item>
<item>
<title>$title</title>
<guid>$guid</guid>
<author>$author</author>
<description>$description</description>
<enclosure0>$url0</enclosure0>
<enclosure1>$url</enclosure>
</item>
</channel>
Well you can simly use normal string concatenation to write the xml file(alternatively you could spend time doing it the hard way with an xml object, which some might consider more proper).
Next you open a file with fopen() in write mode. if the file doesn't exist, it will be created. make sure you have permission to write to that directory, or the file will not be written(and if error reporting is strict, a fatal error will be thrown, else just a warning). second, you use fwrite() to write to the file.for more information, read the manual on filesystem functions
$file = '/path/to/mynewxmlfile.xml';
$data =
'
<?xml version="1.0"?>
<channel>
<title>'.$channel_title.'</title>
<link>'.$channel_link.'</link>
<managingEditor>'.'$managingEditor.</managingEditor>
<channel_description>'.$channel_description.'</channel_description>
';
for($i = 0; $i < 7; $i++){
$pubDate = $xml->channel->item[$i]->pubDate;
$title = $xml->channel->item[$i]->title;
$link = $xml->channel->item[$i]->link;
$guid = $xml->channel->item[$i]->guid;
$author = $xml->channel->item[$i]->author;
$description = $xml->channel->item[$i]->description;
$url0 = $xml->channel->item[$i]->enclosure->attributes()->url;
for($ii = 0; $ii < 2; $ii++){
$url = $xml->channel->item[$i]->enclosure[$ii]->attributes()->url;
}
$data .=
'
<item>
<title>'.$title.'</title>
<guid>'.$guid.'</guid>
<author>'.$author.'</author>
<description>'.$description.'</description>
<enclosure0>'.$url0.'</enclosure0>
<enclosure1>'.$url.'</enclosure1>
</item>
';
}
$data .= '</channel>';
fwrite(fopen($file,'w'),$data);
Alternatively, you could use simplexml_load_string() to load the string as xml, then use asXml() to write it to disk, like so:
$data = simplexml_load_string($data);
$data->asXml($file);
Read the docs http://php.net/manual/en/simplexmlelement.asxml.php
$xml->asXml('rss.xml');
Edit
and if you want to create a new xml there is an answer https://stackoverflow.com/a/143192/1742977
Related
I want to remove all product with category=phones from my xml:
<SHOP>
<ITEM>
<CATEGORY>Computers</CATEGORY>
<NAME>DELL</NAME>
</ITEM>
<ITEM>
<CATEGORY>Computers</CATEGORY>
<NAME>IBM</NAME>
</ITEM>
<ITEM>
<CATEGORY>Phones</CATEGORY>
<NAME>Apple</NAME>
</ITEM>
</SHOP>
I tried this solutions:
$doc = new DomDocument();
$doc->load('product.xml');
$xpath = new DomXPath($doc);
$nodes = $xpath->query('ITEM/CATEGORY');
for ($i = 0; $i < $nodes->length; $i++) {
$node = $nodes->item($i);
if ($node->nodeValue == 'Phones') {
$node->parentNode->removeChild($node);
}
}
But it delete only attribute CATEGORY but I need to delete all ITEM node with thit category. How should i change the code?
You were removing category from item. You want to remove item from shop (Both parents). Easiest way to do this:
$node->parentNode->parentNode->removeChild($node->parentNode);
See it in action at 3v4l here:
<?php
$xml_string = <<<EOT
<SHOP>
<ITEM>
<CATEGORY>Computers</CATEGORY>
<NAME>DELL</NAME>
</ITEM>
<ITEM>
<CATEGORY>Computers</CATEGORY>
<NAME>IBM</NAME>
</ITEM>
<ITEM>
<CATEGORY>Phones</CATEGORY>
<NAME>Apple</NAME>
</ITEM>
</SHOP>
EOT;
$doc = new DomDocument();
$doc->loadXML($xml_string);
$xpath = new DomXPath($doc);
$nodes = $xpath->query('ITEM/CATEGORY');
for ($i = 0; $i < $nodes->length; $i++) {
$node = $nodes->item($i);
if ($node->nodeValue == 'Phones') {
$node->parentNode->parentNode->removeChild($node->parentNode);
}
}
echo $doc->saveXML();
$var1 = new SimpleXMLElement('CSVXML/xvar.xml', null, true);
$var2 = new SimpleXMLElement('CSVXML/yvar.xml', null, true);
let's say I get variables from two diffrents XML files, in the first XML files
<Number>3698</Number>
<InternalNumber>1</InternalNumber>
<Name>Bob</Name>
<Number>3500</Number>
<InternalNumber>2</InternalNumber>
<Name>Mike</Name>
<Number>2775</Number>
<InternalNumber>3</InternalNumber>
<Name>Dan</Name>
in the second XML I get the followings
<player>3698</player>
<group>A</group>
I do this
$varID = $var1->Number;
$varnumber = $var2->player;
if ($varID == $varnumber ){
echo '$var1->InternalNumber';
}
is this possible ?
I simply want to put out a variable, is A for XML! = B from XML2, is there anyway possible to do that?
I found this working fine. tested link
<?php
$str = <<<XML
<items>
<item>
<Number>3698</Number>
<InternalNumber>1</InternalNumber>
<Name>Bob</Name>
</item>
<item>
<Number>3500</Number>
<InternalNumber>2</InternalNumber >
<Name>Mike</Name>
</item>
<item>
<Number>2775</Number>
<InternalNumber>3</InternalNumber>
<Name>Dan</Name>
</item>
</items>
XML;
$str2 = <<<XML
<item>
<player>3698</player>
<group>A</group>
</item>
XML;
$da = new SimpleXMLElement($str2);
$varnumber = $da->player;
$data = new SimpleXMLElement($str);
foreach ($data->item as $item)
{
$this_number = $item->Number;
//echo $this_number."-".$item->InternalNumber."-".$varnumber."\n";
if((int)$this_number == (int)$varnumber ){
$this_internalnumber = $item->InternalNumber;
echo $this_internalnumber."\n";
}
else{
echo "No Match found \n";
}
}
Hope this helps.
I need to display only the image from the CDATA content.
<item>
<title>... </title>
<link>... </link>
<description>... </description>
<category>... </category>
<pubDate>... </pubDate>
<guid>... </guid>
<content:encoded><![CDATA[<img alt="" src="..."/>...]]></content:encoded>
<enclosure url="..." type="image/jpeg" length="171228"></enclosure>
</item>
my code i tried looks like this an works fine for the part
<?php
$html = "";
$url = "http://www....";
$xml = simplexml_load_file($url);
for($i = 0; $i < 1; $i++){
//works fine with <description> part
$description = $xml->channel->item[$i]->description;
preg_match("/<img[^>]+\>/i", $description, $matches);
if (isset($matches[0])) {
$html .= $matches[0];
//echo "<br/>show img<br/>";
} else {
$html .= $description;
echo "<br/>there is no img";
}
}
echo $html;
?>
now i need a method for the part and show the image separately.
can someone help me fix this?
maybe it is possible to use the url in to display the image.
I would like to generate files from xml, I try this but it not working:
<?php
$file0 = "fle0.php";
$file1 = "fle1.php";
$file2 = "fle2.php";
$file3 = "fle3.php";
$file4 = "fle4.php";
$file5 = "fle5.php";
$file6 = "fle6.php";
$file7 = "fle7.php";
$file8 = "fle8.php";
$file9 = "fle9.php";
$html = "";
$url = "http://website.com/file.xml";
$xml = simplexml_load_file($url);
for($i = 0; $i < 10; $i++){
$link = $xml->books[$i]->link;
$title = $xml->books[$i]->title;
$html .= "$title";
file_put_contents($file[$i], $html);
}
?>
Can I use file_put_contents in for loop?
Here is the XML file:
<response>
<books>
<link>http:/www.website.com/linktobook/1.html</link>
<title>Book Title 1</title>
<image>http:/www.website.com/linktobook/1.jpg</image>
</books>
<books>
<link>http:/www.website.com/linktobook/2.html</link>
<title>Book Title 2</title>
<image>http:/www.website.com/linktobook/2.jpg</image>
</books>
<books>
<link>http:/www.website.com/linktobook/3.html</link>
<title>Book Title 3</title>
<image>http:/www.website.com/linktobook/3.jpg</image>
</books>
</response>
It is working without loop when I use $xml->books[0]->link; and $xml->books[1]->link; etc.
Thanks to: Jack
The answer is: change $file[$i] to ${"file$i"}
I am trying to edit some XML with PHP. Currently the XML looking something like:
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Main Title</title>
<link>http://exmaple.com</link>
<description> blahblahblah </description>
<language>en</language>
<item>
<title>Tite1</title>
<link>http://www.example.com (THIS IS WHAT I WANT)</link>
<description>blah blah blah</description>
</item>
.
.
.
</channel>
</rss>
I've tried to access the 2nd level link but my code only changes the first Link node value. Here is the code:
$xml->load('http://www.google.com/doodles/doodles.xml');
$element = $xml->getElementsByTagName('channel')->item(0);
$secondlvl = $element->getElementsByTagName('item')->item(0);
$2ndlevellinknode = $element->getElementsByTagName('link')->item(0);
$2ndlevellinknode->nodeValue = $newvalue;
Any suggestions? Also is it possible to use this line of code in a for loop like this
for ($i = 0; $i <= 20; $i++) {
$element = $xml->getElementsByTagName('channel')->item(0);
$secondlvl = $element->getElementsByTagName('item')->item(0);
$2ndlevellinknode = $element->getElementsByTagName('link')->item($i);
$2ndlevellinknode->nodeValue = $newvalue;
}
this should give you an idea.
$f = simplexml_load_file('test.xml');
print $f->channel->title . "\n";
print $f->channel->link . "\n";
print $f->channel->description . "\n";
foreach($f->channel->item as $item) {
print $item->title . "\n";
}