How to create a sitemap in CodeIgniter - php

I am trying to create a sitemap in codeigniter. But I am facing some errors please help to fix this.
Here is the sitemap.php code
<?php echo '<?xml version="1.0" encoding="UTF-8" ?>'; ?>
<urlset
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">
<!-- created with Free Online Sitemap Generator www.xml-sitemaps.com -->
<url>
<loc>http://example.com/</loc>
<priority>1.0</priority>
</url>
<url>
<loc>http://example.com/contact</loc>
<priority>1.0</priority>
</url>
</urlset>
Controller
public function sitemap(){
$data = "";//select urls from DB to Array
header("Content-Type: text/xml;charset=iso-8859-1");
$this->load->view("sitemap",$data);
}
ERROR
XML Parsing Error: XML or text declaration not at start of entity
Location: http://localhost/hotel/index.php/sitemap.xml
Line Number 2, Column 1:<?xml version="1.0" encoding="UTF-8"?>
^

Related

How to create a new file and save to root directory when updating a post?

I'm trying to create a function that runs when I save a post in wordpress. I need it to create a new file when I save and put it in the root directory.
I've tried the below code but it isn't saving a file anywhere that I can see.
function create_custom_xml_sitemap($post_ID, $post_after, $post_before)
{
$xmlString = '<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.codexworld.com</loc>
<lastmod>2016-07-04T07:46:18+00:00</lastmod>
<changefreq>always</changefreq>
<priority>1.00</priority>
</url>
</urlset>';
$xml = new DOMDocument;
$xml->preserveWhiteSpace = false;
$xml->loadXML($xmlString);
$xml->save('xml/sitemap2.xml');
}
add_action('post_updated', 'create_custom_xml_sitemap', 10, 3);

Add string to sitemap.xml file inside <urlset> tag in PHP

I tried to add a string into the sitemap.xml file inside <urlset> tag, but it stores differently.
<?php
$date_mod = date('Y-m-d');
$sitemap = "<url>
<loc>http://www.website.com/article.php?page=3</loc>
<lastmod>$date_mod</lastmod>
<priority>0</priority>
</url>";
$xml = simplexml_load_file("sitemap.xml");
$xml->addChild($sitemap);
file_put_contents("sitemap.xml", $xml->asXML());
?>
The output is like:
<?xml version="1.0"?>
<urlset>
<url>
<loc>http://www.website.com/article.php?page=3</loc>
<lastmod>2018-01-12</lastmod>
<priority>0</priority>
</url>
<//www.website.com/article.php?page=3</loc>
<lastmod>2018-01-12</lastmod>
<priority>0</priority>
</url>/></urlset>
Please help me.
If the raw xml is like this:
<?xml version="1.0"?>
<urlset>
</urlset>
And you updated xml is like this:
<?xml version="1.0"?>
<urlset>
<url>
<loc>http://www.website.com/article.php?page=3</loc>
<lastmod>2018-01-12</lastmod>
<priority>0</priority>
</url>
</urlset>
Then you could refer to the following code:
<?php
$date_mod = date('Y-m-d');
$sitemap = "<url>
<loc>http://www.website.com/article.php?page=3</loc>
<lastmod>$date_mod</lastmod>
<priority>0</priority>
</url>";
$sitemap_node =simplexml_load_string($sitemap);
$xml = simplexml_load_file("sitemap.xml");
sxml_append($xml,$sitemap_node);
$xml->asXML('sitemap.xml');
function sxml_append(SimpleXMLElement $to, SimpleXMLElement $from) {
$toDom = dom_import_simplexml($to);
$fromDom = dom_import_simplexml($from);
$toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));
}
?>
Your previous code failed to do that is because addChild method can only deal with text (and stil has some drawbacks), not another xml object.

PHP/XML Delete Child in image Sitemap

I have a XML image Sitemap for google like:
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
<url>
<loc>http://www.domain.de</loc>
<image:image>
<image:loc>http://www.domain.de/image1.jpg</image:loc>
<image:title>image 1</image:title>
</image:image>
<image:image>
<image:loc>http://www.domain.de/image2.jpg</image:loc>
<image:title>image 2</image:title>
</image:image>
</url>
</urlset>
Now I will delete a "image:image" child where "image:loc" is like "http://www.domain.de/image2.jpg".
How can I do this with php?
I have tested code like the following:
$xmlPageUrl="http://www.domain.de/image2.jpg";
foreach($sitemap->xPath('//url[image:image/image:loc="' . $xmlPageUrl . '"]') as $node) {
$sitemap->parentNode->removeChild($node);
}
Who can help me?
Use can use text() in xpath to search for specific content :
//image:image/image:loc[text()="http://www.domain.de/image2.jpg"]
so :
$doc = new DOMDocument;
$doc->loadxml($xmlString);
$xpath = new DOMXpath($doc);
$xmlPageUrl="http://www.domain.de/image2.jpg";
foreach($xpath->query('//image:image/image:loc[text()="'.$xmlPageUrl.'"]') as $node) {
$node->parentNode->parentNode->removeChild($node->parentNode);
}
the XML now contains :
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
<url>
<loc>http://www.domain.de</loc>
<image:image>
<image:loc>http://www.domain.de/image1.jpg</image:loc>
<image:title>image 1</image:title>
</image:image>
</url>
</urlset>

How can I add a Child in my xml file with fwrite

I have a problem when I try to insert a new node to my xml file. I need to add:
<ul><loc> mylink</ul></loc>
before the last node in my xml file.
I tried the code below, but it doesn't work and it breaks the last node before I insert the new one:
$userfile = "sitemap.xml";
$fh = fopen($userfile, 'r+');
$addUser = "<url><loc>https://www.example.com/Privacy-Policy</loc></url></urlset> ";
fseek($fh, -10, SEEK_END);
fwrite($fh, $addUser);
fclose($fh);
This is part of my xml file:
<urlset >
<url>
<loc>example.com</loc>
</url>
<url>
<loc>example.com</loc>
</url>
</urlset>
my output is:
<urlset >
<url>
<loc>example1.com</loc>
</url>
<url>
<loc>example2.com</loc>
</ur<url> //<-- See here my xml file broke
<loc>example2.com</loc>
</url>
</urlset>
This should work for you:
(Here I just load the xml file with simplexml_load_file(), to create a SimpleXMLElement(). After this you can simply add a child to the root node)
<?php
$xml = simplexml_load_file("file.xml");
$xml = new SimpleXMLElement($xml->asXML());
$urlChild = $xml->addChild("url", "");
$urlChild->addChild("loc", "example2.com");
$xml->asXML("file.xml");
?>
input file:
<urlset >
<url>
<loc>example.com</loc>
</url>
<url>
<loc>example.com</loc>
</url>
</urlset>
output file:
<?xml version="1.0"?>
<urlset>
<url>
<loc>example.com</loc>
</url>
<url>
<loc>example.com</loc>
</url>
<url>
<loc>example2.com</loc>
</url>
</urlset>

PHP DOMDocument not formatting output correctly

I'm currently working on the sitemaps for a website, and I'm using SimpleXML to import and do some checks on the original XML file. after this I use simplexml_load_file("small.xml"); to convert it to DOMDocument to make it easier to precisely add and manipulate XML elements. Below is the test XML sitemap that i'm working from:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:52:32-Orouke.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:53:23-castle technology.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:53:38-banana split.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:53:42-Waveney.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:55:12-pure orange.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:57:54-tau press.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:59:21-E.f.m.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:59:31-apple.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:59:45-townhouse communications.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
</urlset>
Now. here is the test code I'm using to modify:
<?php
$root = simplexml_load_file("small.xml");
$domRoot = dom_import_simplexml($root);
$dom = $domRoot->ownerDocument;
$urlElement = $dom->createElement("url");
$locElement = $dom->createElement("loc");
$locElement->appendChild($dom->createTextNode("www.google.co.uk"));
$urlElement->appendChild($locElement);
$lastmodElement = $dom->createElement("lastmod");
$lastmodElement->appendChild($dom->createTextNode("2011-08-02"));
$urlElement->appendChild($lastmodElement);
$domRoot->appendChild($urlElement);
$dom->formatOutput = true;
echo $dom->saveXML();
?>
The main problem is, that no matter where i place $dom->formatOutput = true; the existing XML that was imported from SimpleXML is formatted correctly, but anything new is formatted in the "all one line" style, as follows:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:52:32-Orouke.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:53:23-castle technology.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:53:38-banana split.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:53:42-Waveney.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:55:12-pure orange.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:57:54-tau press.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:59:21-E.f.m.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:59:31-apple.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url>
<loc>http://www.companycheck.co.uk/searches/2011/08/22/23:59:45-townhouse communications.html</loc>
<lastmod>2011-08-23</lastmod>
</url>
<url><loc>www.google.co.uk</loc><lastmod>2011-08-02</lastmod></url></urlset>
If anyone has an idea why this is happening and how to fix it I would be very grateful.
There is a workaround. You can force reformatting by saving your new xml to string first, then load it again after setting the formatOutput property, e.g.:
$strXml = $dom->saveXML();
$dom->formatOutput = true;
$dom->loadXML($strXml);
echo $dom->saveXML();
To format output nicely, you need to set the preserveWhiteSpace variable to false before loading as stated in the documentation
Example:
$Xhtml = "<div><span></span></div>";
$doc = new DOMDocument('1.0','UTF-8');
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
$doc->loadXML($Xhtml);
$formattedXhtml = $doc->saveXML($doc->documentElement, LIBXML_NOXMLDECL);
$expectedFormatting =<<<EOF
<div>
<span/>
</div>
EOF;
$this->assertEquals($expectedFormatting,$formattedXhtml,"The XHTML is formatted");
Just for the visitor that comes here as this was the first answer on Google Search.
I had this same problem using code like Simon's.
Turns out that when you disable errors (either with $doc->loadHTML(..., LIBXML_NOERROR) or libxml_use_internal_errors(true);), it won't format anymore (example: https://3v4l.org/ur76E).
The solution is to not disable errors and suppress them on the PHP side (with #).
Ugly, but it works: https://3v4l.org/BSJVu
The final silver bullet function looks like:
function beautifyDoc(DOMDocument $doc): void
{
$previousLibXmlState = libxml_use_internal_errors(false);
$previousErrorHandler = set_error_handler(null);
try {
$html = $doc->saveHTML();
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
#$doc->loadHTML($html);
} finally {
libxml_use_internal_errors($previousLibXmlState);
set_error_handler($previousErrorHandler);
}
}
// usage
$doc = new DOMDocument();
// ...load html and do stuff...
beautifyDoc($doc);
echo $doc->saveHTML(); // done
(it also takes care of the php error handler, if already set)

Categories