I have two XML documents, both formatted like this:
<?xml version="1.0" ?>
<article>
<body>
<![CDATA[
*some text*
]]>
</body>
</article>
and I want to echo them using this:
<?php
$xml = simplexml_load_file("." . $filename);
echo $xml->body;
?>
But one of them works, the other just echos nothing. What is going on?
UPDATE:
The document which produces the error contains this appostrophe: '
When this apostrophe is removed, the code works. I need some way of escaping characters like this, how can I do it?
Just echo asXML() you may see your error with the second file.
echo $xml->asXML();
Here is a simple tutorial on SimpleXML: http://php.net/manual/en/simplexml.examples-basic.php
Espace your appostrophe:
<?php
$text = file_get_contents("." . $filename);
$text = str_replace("'", "'", $text);
$xml = simplexml_load_string($text);
echo $xml->body;
?>
Also, someone had a similar problem (no crash but garbage characters) and came up with the same solution. A bit later in that forum thread they speculate on utf8_encode and utf8_decode, which you could also try. Link: http://board.phpbuilder.com/showthread.php?10359181-RESOLVED-SimpleXML-apostrophe-problem&p=10886946&viewfull=1#post10886946
Related
I'm working on a very simple RSS Feed. What I am doing is pulling the information from a database and transforming it into XML using PHP. However, when I use Chrome to look at the code to make sure it is all appearing as it should, I get these errors at the top of the page.
Here is the code that I am using to pull from my database and create the RSS Feed.
<?php
include('connectDatabaseScript.php');
$sql = "SELECT * FROM table ORDER BY id DESC";
$query = mysql_query($sql) or die(mysql_error());
header("Content-type: text/xml");
echo "<?xml version='1.0' encoding='UTF-8'?>
<rss version='2.0'>
<channel>
<title>My RSS Feed</title>
<link>http://www.mywebsite.com/rss.php</link>
<description>The description for the feed.</description>
<language>en-us</language>";
while($row = mysql_fetch_array($query)) {
$title=$row['title'];
$finalTitle = str_replace("&", "and", $title);
$link=$row['link'];
$newLink = str_replace("&", "&", $link);
$category = $row['category'];
$date = $row['date'];
$description = $row['description'];
echo "<item>
<title>$finalTitle</title>
<link>$newLink</link>
<description>$description</description>
<author>John Doe</author>
<pubDate>$date<pubDate>
<category>$category</category>
</item>";
}
echo "</channel></rss>";
?>
This code usually gets stuck on the title tag. When it does that, it will merge together the link and can also merge the rest of the item and several others after it. Here is an example of what is happening.
<item>
<title>Title No 415: Title <item>
<title>Title No 291: Another Title</title>
<link>http://www.mywebsite.com/post.php?id=291</link>
<description>description</description>
<author>John Doe</author>
<pubDate>Jan. 1, 2000</pubDate>
<category>Generic</category>
</item>
I have figured out what character is causing this to occur. It is the "–" character that appears in some of the titles that I have that is causing the problem. I've been trying to remove it by using the str_replace function. While I have been able to use it with "&" with success, it is not working with "–". Is there another solution to get rid of the "–" from the title or is it still possible with str_replace?
You should not write your XML like this. To avoid this kind of errors, you may use DOMDocument to write your XML, and save it using saveXML.
I have some PHP scripts that make a MySQL query and use it to produce an RSS feed. The text for RSS elements such as title and description needs to be cleaned up for presentation as XML.
Here's a function to do that:
function clean_text($in_text) {
return utf8_encode(
htmlspecialchars(
stripslashes($in_text)));
}
I think a simpler function might solve the problem you're having:
function clean_text($in_text) {
return htmlspecialchars(
stripslashes($in_text));
}
The call to utf8_encode() encodes an ISO-8859-1 string as UTF-8 and was necessary for me because I was dealing with ISO-8859-1 character encoding in my database. The htmlspecialchars() function in PHP turns & to &, < to < and > to >.
Here's a statement that uses the function to output some RSS:
echo "<description>" . clean_text($row['description']) . "</description>";
I am getting a a request like this and the url looks like this : http://domain.com/page.php?text={Arabic Word}
Now am trying to get the text using $_GET['text'] but i keep getting it like "????????" , whats the problem
<?php
header('Content-type: text/html; charset=UTF-8');
include('EnTransliteration.class.php');
$tr = new EnTransliteration();
$str = iconv( "utf-8//TRANSLIT//IGNORE","windows-1256", $_GET['text']);
$en_str = $tr->ar2en($str);
$string = <<<XML
<root>
<translation>$en_str</translation>
</root>
XML;
$xml = new SimpleXMLElement($string);
header('Content-type: text/xml; charset=UTF-8');
echo $xml->asXML();
?>
Your Apache server probably doesn't accept UTF-8 URL encoding. See this answer to solve your problem.
Hope it will help :)
Your HTML form needs to explicitly declare that the data must be sent as UTF-8. Otherwise, it will use the user's locale, which may not mean windows-1256, and certainly doesn't mean UTF-8.
e.g.
<form action="" method="get" accept-charset="UTF-8">
maybe this can help :
<?php
$title = 'أبجد هوز';
$path1 = '/product/'.rawurlencode($title);
echo $path1."<br>";
$path2 = rawurldecode($path1);
echo $path2;
?>
1-open start
2-open notepad
3-write your code
4-when you saving file make Encoding: utf-8
5-file name name.html name.php
I have build a simple site map script, i am not able to get URL output in URL field.
My PHP Script.
header("Content-Type: text/xml;charset=iso-8859-1");
echo '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
';
require_once('_ls-global/php/sr-connect.php');
$db = mysql_select_db($database,$connection) or trigger_error("SQL", E_USER_ERROR);
$sqlquery = mysql_query("SELECT * FROM $tablename ORDER by id")or die (mysql_error());
while ($list = mysql_fetch_assoc($sqlquery)){
$pflink=$list['pflink'];
$pagelink=$list['pagelink'];
$site="http://mysite.com";
$url='$site/$pflink/$pagelink';
$changefreq="weekly";
$priority="1.0";
echo '<url>
<loc>'.$url.'</loc>
<changefreq>'.$changefreq.'</changefreq>
<priority>'.$priority.'</priority>
</url>';
}
echo '</urlset>';
The Output of this script is this.
<url>
<loc>$site/$pflink/$pagelink</loc>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
If i change $url='$site/$pflink/$pagelink'; to $url="$site/$pflink/$pagelink";
then i get only one value and error "XML Parsing Error: not well-formed".
Please see and suggest any modification to make it work.
Thanks
I guess you are having characters in the vars which are messing up the XML.
For example &, ä, <, >... You need to encode the content correctly.
Try wrapping the output:
At first change $url to $url = $site .'/'. $pflink .'/'. $pagelink; and then update the output of the XML to:
<?php
// ...
echo '<url>
<loc><![CDATA['.$url.']]></loc>
<changefreq>'.$changefreq.'</changefreq>
<priority>'.$priority.'</priority>
</url>';
?>
Explanation to CDATA available at http://en.wikipedia.org/wiki/CDATA
Based on thedom and FrontEndJohn answers and comment I got it right this way.
Changing $url='$site/$pflink/$pagelink'; to $url = $site .'/'. $pflink .'/'. $pagelink;
And modifying.
echo '<url>
<loc>'.$url.'</loc>
<changefreq>'.$changefreq.'</changefreq>
<priority>'.$priority.'</priority>
</url>';
to
echo '<url>';
echo '<loc><![CDATA['.$url.']]></loc>';
echo '<changefreq>'.$changefreq.'</changefreq>';
echo '<priority>'.$priority.'</priority>';
echo '</url>';
Hope this helps others too.
If I understand your problem correctly, you cannot currently get the value of the variable due to the use of ' but when trying to use " so that the variables echo the XML gets upset.
Try:
$url = $site . '/' . $pflink . '/' . $pagelink;
This will give the value of the variables without using ". If I have miss-understood you please let me know.
Edit: Thinking about it, it looks more the the value of one or more of the variables may be what is upsetting the XML, assuming the variables are not giving their values while using '. It could be worth checking the contents of the variables for issues if you have not done so already.
I have a slight problem. I need to parse a file and populate a web banner with the results. Problem is, the file is called : "_banner_products.php" and it's contents are as follows:
<?php header('Content-Type:text/xml'); ?><?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<carouselle>
<firstLayer>
<layerName>Leica Disto X310</layerName>
<layerProduct>Disto X310</layerProduct>
<layerPic>http://www.leicaestonia.ee/extensions/boxes_design/flashpics/1334482548.jpg</layerPic>
<layerPrice>0,-</layerPrice>
<layerPriceOld></layerPriceOld>
<layerLink>http://www.leicaestonia.ee/index.php?id=11627</layerLink>
<layerTimer>01.05.2012 00:00</layerTimer>
</firstLayer>
<firstLayer>
.....
.....
</firstLayer>
</carouselle>
How can I loop through this file to group all the "firstLayer" children into one and so on..
If I just use:
$file = fopen("_banner_products.php", "r");
while (!feof($file)){
$line = fgets($file);
}
simplexml_load_file throws this-
"_banner_products.php:1: parser error : Start tag expected, '<' "
Then I only get the contents of the <...> tags meaning there is no way for me to differentiate if I am out of the scope already.
Thanks for anyone responding. If anything is unclear I´ll try to explain more.
EDIT.
Thank you for the solution, indeed using the full URL worked:
simplexml_load_file("http://localhost/MySite/_banner_products.php");
You are having issue because simplexml_load_file is treating your file like a local xml file .. what you need to do is add the full URL
Example
simplexml_load_file("http://localhost/web/_banner_products.php");
Use Case getting layerName for example
_banner_products.php
<?php
header ( 'Content-Type:text/xml' );
echo '<?xml version="1.0" encoding="UTF-8"?>';
?>
<carouselle>
<firstLayer>
<layerName>Leica Disto X310</layerName>
<layerProduct>Disto X310</layerProduct>
<layerPic>http://www.leicaestonia.ee/extensions/boxes_design/flashpics/1334482548.jpg</layerPic>
<layerPrice>0,-</layerPrice>
<layerPriceOld></layerPriceOld>
<layerLink>http://www.leicaestonia.ee/index.php?id=11627</layerLink>
<layerTimer>01.05.2012 00:00</layerTimer>
</firstLayer>
<firstLayer>
<layerName>Leica Disto X310</layerName>
<layerProduct>Disto X310</layerProduct>
<layerPic>http://www.leicaestonia.ee/extensions/boxes_design/flashpics/1334482548.jpg</layerPic>
<layerPrice>0,-</layerPrice>
<layerPriceOld></layerPriceOld>
<layerLink>http://www.leicaestonia.ee/index.php?id=11627</layerLink>
<layerTimer>01.05.2012 00:00</layerTimer>
</firstLayer>
</carouselle>
view details
$xml = simplexml_load_file("http://localhost/lab/stockoverflow/_banner_products.php");
echo "<pre>" ;
foreach($xml as $key => $element)
{
echo $element->layerName , PHP_EOL ;
}
The most obvious way to do this is to strip out the first line, and add the XML declaration back in with your code.
You could also parse the file with PHP, using eval(), but be very sure about what you are parsing, as this could be a very large security hole.
I've successfully integrated the LinkedIn API with my website, but I'm struggling to extract information from the XML. At the moment I'm just trying to print it out so I can proceed to use the user's information once they have logged in and given permission.
Below is the format of the XML, and further down is the code I am using to extract the information. The "first name", "last name" and "headline" calls work perfectly, but where an element has sub-headings, nothing is printed out. I've tried using
echo 'Positions: ' . $xml->{'positions:(title)'};
but it doesn't work.
Here is the XML:
<person>
<id>
<first-name />
<last-name />
<headline>
<location>
<name>
<country>
<code>
</country>
</location>
<industry>
<summary/>
<positions total="">
<position>
<id>
<title>
<summary>
<start-date>
<year>
<month>
</start-date>
<is-current>
<company>
<name>
</company>
</position>
</person>
This is the code I've been using to try to extract the information. I know I have to include the sub-heading somehow but I just don't know how!
echo 'First Name: ' . $xml->{'first-name'};
echo '<br/>';
echo 'Last Name: ' . $xml->{'last-name'};
echo '<br/>';
echo 'Headline: ' . $xml->{'headline'};
echo '<br/>';
echo 'Positions: ' . $xml->{'positions'};
Any help would be greatly appreciated, thanks for reading!
Using SimpleXML, you'd access the LinkedIn XML data properties as follows:
Anything with a dash in the property gets {}, so first-name becomes:
$xml->{'first-name'}
Anything without a dash such as headline, is referenced like:
$xml->headline
Anything that is a collection, such as positions, is referenced like:
foreach($xml-positions as $position) {
echo $position->title;
echo $position->{'is-current'};
}
Your XML is not valid, its not well formed. Anyway here's a sample XML and how to use it.
$v = <<<ABC
<vitrine>
<canal>Hotwords</canal>
<product id="0">
<descricao>MP3 Apple iPod Class...</descricao>
<loja>ApetreXo.com</loja>
<preco>à vista R$765,22</preco>
<urlImagem>http://im</urlImagem>
<urlProduto>http://</urlProduto>
</product>
</vitrine>
ABC;
$xml = simplexml_load_string($v);
foreach ($xml->product as $c){
echo $c->loja; //echoing out value of 'loja'
}
Try to use PHP's XML Parser instead:
http://www.php.net/manual/en/function.xml-parse.php
Tried Paul's answer above for:
foreach($xml-positions as $position) {
echo $position->title;
echo $position->{'is-current'};
}
didn't work for me - so I used this - not as elegant but works
for($position_num = 0; $position_num < 10;$position_num++){
echo $xml->positions->position[$position_num]->company->name;
}
Your XML is not well-formed... there are several elements without close tags. So we have no way to know for sure the structure of your XML. (You can't do that in XML like you can in HTML.)
That being said, assuming that <person> is the context node, you can probably get the content of the <title> element using an XPath expression, as in
$xml->xpath('positions/position/title');
I'm assuming $xml is a SimpleXMLElement object.