Data feed created in php doesn't validate - php

I have to following code to upload data to a third party. However when I test it in a validator I get the following error:
Undefined root elements:items and text/xml media type is not specific enough.
I have no clue has what I need to change.
Here is the code:
header('Content-Type: text/xml');
echo '<?xml version="1.0" encoding="UTF-8"?>
<items>';
mysql_select_db($database_dconn, $dconn);
$query_feed = "SELECT * FROM dat_table WHERE time BETWEEN (NOW() - INTERVAL 7 DAY) AND NOW()";
$feed = mysql_query($query_feed, $dconn) or die(mysql_error());
while ($row_feed = mysql_fetch_assoc($feed)){
echo'<item>
<name>'.$row_feed['Name'].'</name>
<email>'.$row_feed['email'].'</email>
<date>'.$row_feed['Date'].'</date>
<description>'.$row_feed['Make'].' '.$row_feed['Model'].' '.$row_feed['Type'].'</description>
<logon>'.$row_feed['Logon'].'</logon>
<category>'.$row_feed['Type'].'/'.$row_feed['Make'].'</category>
<product_search_code>'.$row_feed['Product_search_code'].'</product_search_code>
<order_ref>'.$row_feed['Invoice'].'</order_ref>
<product_link>'.$row_feed['Product_link'].'</product_link>
<customer_ref>'.$row_feed['Invoice'].'</customer_ref>
<amount>'.$row_feed['Price'].'</amount>
<currency>GBP</currency>
</item>';
}
echo '</items>
';
This is RSS out put in validator:
<?xml version="1.0" encoding="UTF-8"?>
<items><item>
<name>Name of customer</name>
<email>customer#gmail.com</email>
<date>03/04/2014</date>
<description>Roland FP80BK Piano</description>
<logon>www.pianoandkeyboardshoponline.co.uk</logon>
<category>Piano/Roland</category>
<product_search_code>264</product_search_code>
<order_ref>8336</order_ref>
<product_link>http://www.pianoandkeyboardshop.co.uk/Roland-FP80-Digital-Piano-in-Satin-Black/264</product_link>
<customer_ref>8336</customer_ref>
<amount>1500.00</amount>
<currency>GBP</currency>
</item><item>
next item etc
---
--
</item><items>
Any help is really appreciated.

The text/xml content type is for generic XML documents. For a feed, try using
header('Content-Type: application/rss+xml');
But anyway, in order to create a valid RSS you have to use the correct RSS tags (Something like this). You seem to use a lot of custom tags instead, so I don't know what exactly you need to do. The easiest solution would be to use namespaces for your custom tags, so something like:
header('Content-Type: application/rss+xml');
echo '<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:mytags="http://mytags.something.net">
<channel>
<title>My RSS Title</title>
<description>This is the description for my RSS feed</description>
<link>http://www.someexamplerssdomain.com/main.html</link>
<mytags:items>';
mysql_select_db($database_dconn, $dconn);
$query_feed = "SELECT * FROM dat_table WHERE time BETWEEN (NOW() - INTERVAL 7 DAY) AND NOW()";
$feed = mysql_query($query_feed, $dconn) or die(mysql_error());
while ($row_feed = mysql_fetch_assoc($feed)){
echo '<mytags:item>
<mytags:name>'.$row_feed['Name'].'</mytags:name>
<mytags:email>'.$row_feed['email'].'</mytags:email>
<mytags:date>'.$row_feed['Date'].'</mytags:date>
<mytags:description>'.$row_feed['Make'].' '.$row_feed['Model'].' '.$row_feed['Type'].'</mytags:description>
<mytags:logon>'.$row_feed['Logon'].'</mytags:logon>
<mytags:category>'.$row_feed['Type'].'/'.$row_feed['Make'].'</mytags:category>
<mytags:product_search_code>'.$row_feed['Product_search_code'].'</mytags:product_search_code>
<mytags:order_ref>'.$row_feed['Invoice'].'</mytags:order_ref>
<mytags:product_link>'.$row_feed['Product_link'].'</mytags:product_link>
<mytags:customer_ref>'.$row_feed['Invoice'].'</mytags:customer_ref>
<mytags:amount>'.$row_feed['Price'].'</mytags:amount>
<mytags:currency>GBP</mytags:currency>
</mytags:item>';
}
echo '</mytags:items>
</channel>
</rss>';

You have no xmlns (XML name space) defined. Thus the error is probably due to the fact that the root element items is... not defined, as said in the error message. See this link or that link for explanations on xmlns.
First, to complete the previous answer, after the first echo, add a rss-specific line: echo '<rss version="2.0">';
Second, you either need to add an xmlns definition in the above line echo '<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">'; for example, or to change the root element name. try with channel or feed. Better yet, find a feed which is read by the service you want your feed to be read by, and have a look at the beginning of the file; look for xmlns and root element names.
best,

Related

SimpleXML parsing through namespace items with ->children

I am parsing through the following XML file:
testxml.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?><document>
<node id="n0">
<data key="d6">
<y:GenericNode configuration="TEXT I WANT TO GET">
<y:Geometry height="56.030557066666574" width="181.68810666666667" x="638.4599149206349" y="143.24969103333325"/>
<y:Fill color="#FFCC66" color2="#FF9900" transparent="false"/>
<y:BorderStyle color="#000000" type="line" width="1.0"/>
<y:NodeLabel alignment="center" autoSizePolicy="node_width" configuration="CroppingLabel" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="34.265625" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="181.68810666666667" x="0.0" y="10.882466033333287">Text I want to Get<y:LabelModel>
<y:SmartNodeLabelModel distance="4.0"/>
</y:LabelModel>
<y:ModelParameter>
<y:SmartNodeLabelModelParameter labelRatioX="-0.5" labelRatioY="0.0" nodeRatioX="-0.5" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
</y:ModelParameter>
</y:NodeLabel>
</y:GenericNode>
</data>
</node>
I am interested in only a handful of attributes, namely the node id, data key which I am able to get with the code below. However, when I move into the y: namespace I get nothing.
xmlparser.php
<?php
$xml = simplexml_load_file("testxml.xml")
or die("Error: Cannot create object - check that the XML file exists and is
not corrupted"); print_r($xml);
echo $xml->node[0]['id']; // This works
echo $xml->node[0]->data[0]['key']; // This works
echo $xml->children('y', true)->GenericNode->attributes()->configuration; // Nothing
echo $xml->children('y', true)->GenericNode->NodeLabel; // Nothing
?>
I've read through previous answers on similar issues, based on which I adopted the children approach. However I can't get this to work, and I have no idea how to implement some of the other approaches such as declaring namespaces and the xpath approach.
Any help would be greatly appreciated.
That's because y:GenericNode isn't direct child of the root element, so you shouldn't be accessing it directly from $xml :
$xml->node->data->children('y', true)->GenericNode->attributes()->configuration;
quick test : https://eval.in/761412

Getting info from a specific XML Node

I am trying to read the value for 3 specific XML nodes (bill_codes, sent_total, clicked_unique_total) I have done a lot of testing and I feel like I need someone with fresh eyes to look at this and help me find out what I no longer see..
I am using the simplexml_load_string function to load the XML into an array..
Here is the code that I have so far:
$xml = simplexml_load_string($content);
echo $xml->methodResponse->item->responseData->message_data->message->bill_codes;
This is the XML that I am using (comes from an API Call so I have no access to modifying/updating the structure of the XML)
<?xml version="1.0" encoding="utf-8"?>
<methodResponse>
<item>
<methodName>
<![CDATA[legacy.message_stats]]>
</methodName>
<responseData>
<message_data>
<message id="2345456">
<message_subject>
<![CDATA[#1 Item You Should Be Hoarding in 2015]]>
</message_subject>
<date_sent>2014-12-18 04:01:34</date_sent>
<message_notes>
<![CDATA[Sample Notes]]>
</message_notes>
<withheld_total>0</withheld_total>
<globally_suppressed>0</globally_suppressed>
<suppressed_total>0</suppressed_total>
<bill_codes>
<![CDATA[8578]]>
</bill_codes>
<sent_total>734273</sent_total>
<link_append_statement/>
<timezone/>
<message_name>
<![CDATA[Sample Message Name]]>
</message_name>
<optout_total>4054</optout_total>
<optout_rate_total>0.55</optout_rate_total>
<clicked_total>5363</clicked_total>
<clicked_unique>4350</clicked_unique>
<clicked_rate_unique>13.71</clicked_rate_unique>
<campaign_id>228640</campaign_id>
<campaign_type>C</campaign_type>
<included_groups>
<segment id="1208891">
<![CDATA[Segment Name Here]]>
</segment>
</included_groups>
<included_smartlists></included_smartlists>
<excluded_groups></excluded_groups>
<excluded_smartlists></excluded_smartlists>
<attributes></attributes>
<link id="40278272">
<has_name>1</has_name>
<clicked_unique_total>4350</clicked_unique_total>
</link>
</message>
</message_data>
</responseData>
<responseNum>
<![CDATA[1]]>
</responseNum>
<responseCode>
<![CDATA[201]]>
</responseCode>
</item>
</methodResponse>
No need to include the parent, just start with the ->item:
echo $xml->item->responseData->message_data->message->bill_codes;
Sample Output

DOMDocument() xmlns giving "< />" instead of "<>" creating invalid document for google products.

I'm attempting to create a valid product feed for google shopping. All is well except this issue here.
DOMDocument() is creating this:
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0"/>
Whereas the objective is this:
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0">
Note the missing "/"
I thought < /> was perfectly valid code, but google is rejecting it with this error:
XML formatting error - Error
Our system encountered an error when processing your data feed. Learn
more. Examples: Line Nr. 3 Column Nr. 1
That of course relates to the above tag I mentioned.
The doc starts off this way...
<?xml version="1.0"?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" xmlns:c="http://base.google.com/cns/1.0"/>
<channel>
...
I'm not aware there are any issues, yet google says its in error.
<?php
$xml = new DOMDocument();
$rss = $xml->createElement('rss');
$version = $xml->createAttribute('version');
$rss->appendChild($version);
$value = $xml->createTextNode('2.0');
$version->appendChild($value);
$xmlns_g = $xml->createAttribute('xmlns:g');
$rss->appendChild($xmlns_g);
$value = $xml->createTextNode('http://base.google.com/ns/1.0');
$xmlns_g->appendChild($value);
$xmlns_c = $xml->createAttribute('xmlns:c');
$rss->appendChild($xmlns_c);
$value = $xml->createTextNode('http://base.google.com/cns/1.0');
$xmlns_c->appendChild($value);
$xml->appendChild($rss);
?>
Somewhere further in the code you have something that reads like this:
$channel = $xml->createElement('channel');
...
$xml->appendChild($channel);
This is incorrect.
This will add children to the document itself. You must add children to existing nodes, among them the root rss node.
$channel = $xml->createElement('channel');
...
$rss->appendChild($channel);

PHP and XML: Dlvr.it does not work

My feeds are made with PHP and MYSQL into XML and then feedburner.
My problem is that dlvr.it cannot read new entries everytime I post.
Here's my PHP code:
<?php
include('db.php');
header('Content-Type: text/xml');
echo '<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0">
<channel>
<title>MindWeather Thesis</title>
<description>Latest News from my website</description>
<link>http://www.mindweather.info</link>';
$get_articles = "SELECT Fore_ID, Valid, Synopsis,
DATE_FORMAT(Issued,'%a, %e %b %Y %T') as formatted_date
FROM tblforecast ORDER BY Issued DESC LIMIT 15";
$articles = mysql_query($get_articles) or die(mysql_error());
while ($article = mysql_fetch_array($articles)){
echo '
<item>
<title>'.$article['Valid'].'-hour Forecast</title>
<description><![CDATA['.$article['Synopsis'].']]> </description>
<link>http://mindweather.info/fforecast.php?fore='.$article['Fore_ID'].'</link>
<pubDate>'.$article['formatted_date'].' GMT</pubDate>
</item>';
}
echo '</channel>
</rss>';
?>
The feedburner feed is located at: http://www.mindweather.info/feedz2.php
Your answers would be as of much help. Thanks!
The mechanism to detect new entries in a feed is to identify them using their unique <guid>. Since your feed lacks that element, it's perfectly normal that this service cannot detect new entries.
It's as simple has addding something like : <guid><?php echo $article['Fore_ID']; ?></guid>, assuming of course that the Fore_ID is unique. Add them between the <item> and </item>
You should also make sure each <link> element is unique because this is another way feed readers try to detect new/unique entries when they fail to do so using that <guid> element.

How to insert an image tag into XML file?

I am using the following php code to create an XML file:
echo '<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0">
<channel>
<title>mytitle</title>
<description>my description</description>
<link>www.mysite.com</link>';
$sql = "SELECT title, description, url, picture, formatted_date
FROM somewhere" ;
$result = mysql_query($sql);
if (!$result) {
die('Invalid query: ' . mysql_error());
}
if(mysql_num_rows($result)>0)
{
while($result_array = mysql_fetch_assoc($result))
{
//timestamp date to xml format
$pubdate = date('D, d M Y H:i:s O', strtotime($result_array[formatted_date]));
echo '
<item>
<title>'.$result_array[title].'</title>
<description>'.$result_array[description].'</description>
<link>'.$result_array[indit_url].'</link>
<pubDate>'.$pubdate.' GMT</pubDate>
<enclosure url="'.$result_array[picture].'" length="1121990" type="image"/>
<image>
<url>'.$result_array[picture].'</url>
<title>image title</title>
<link>'.$result_array[picture].'</link>
<width>111</width>
<height>33</height>
<description>An amazing picture</description>
</image> </item>';
The file created is correctly validated using http://validator.w3.org/, but when i try to use some xml parser like: http://simplepie.org/ the perser are not able to capture the images. Am i using a correct tag to insert image into xml file? Is there any other tags or method to inser images?
Please try escaping the special characters in the image tag.
Use htmlspecialchars on $result_array[picture]
Also, can you show a sample of your rss feed here so that the answer can be more accurate.
I would suggest surrounding the data in an XML escape structure -as such:
<image>
<url><![CDATA[ imagedatagoeshere ]]></content></url>
</image>
However, I'm not familiar with simplepie, so I don't know if that understands CDATA properly.

Categories