How to Dynamically Generate XML Files Using PHP
  John Mwaniki /   18 Dec 2023

How to Dynamically Generate XML Files Using PHP

In this article, you will learn how to create and modify XML files programatically and dynamically using PHP with the help of multiple practical examples.

While you can manually create XML files, there are scenarios where you would want to automate the process. For instance, you may want the file to be updated with real-time data every time a change is made or new data is added.

At other times, you may have a lot of data obtained from huge database tables or APIs. In that case, it would be difficult, or next to impossible, to manually create/update an XML file with data of that magnitude.

Another example, that we will use for demos in this article, is a website's XML sitemap. An XML sitemap is a file on a website in XML format that comprises a list of URLs to all the important pages on a website, to help search engines, such as Google, find, crawl, and index those pages.

Each URL record comprises information within the <url> tags as in the XML sitemap file below:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
  <loc>https://www.webdevsplanet.com</loc>
  <lastmod>2023-12-15T12:12:30+00:00</lastmod>
  <changefreq>monthly</changefreq>
  <priority>1.0</priority>
</url>
<!-- More url elements for the other page URLS -->
</urlset>

The <loc> element is required and specifies the actual page URL. All the others are optional. The <lastmod> element specifies the date on which the page was last modified, <changefreq> specifies how often the page changes, and <priority> specifies how important the page is compared to other pages on the site, with values from 0.0 to 1.0, where 1.0 is the highest priority.

When a new page is created or an existing one is updated on the site, you would want the new URL to be added to the file or the last modified date to be updated.

For a small website, you can easily do this manually. You can also use an online XML sitemap generator for the same.

However, suppose you have a huge dynamic content website in which new pages/posts are regularly published or updated. In that case, doing it manually or using sitemap generators may not be the ideal way to create and update the sitemap.

In such a case, you would want to automate the process to have the XML file updated automatically.

Creating an XML File in PHP

There are several ways of creating and manipulating (reading and modifying) XML documents in PHP.

In this article, we will use SimpleXML, which is a built-in PHP extension for reading and manipulating XML data.

<?php
$xml = new SimpleXMLElement("<urlset></urlset>");
$url = $xml->addChild("url");
$url->addChild("loc", "https://www.webdevsplanet.com");
$url->addChild("lastmod", "2023-12-16");
$url->addChild("changefreq", "monthly");
$url->addChild("priority", "1.0");
$xml->asXML("sitemap.xml");
?>

Output: A file named "sitemap.xml" with the code below.

<?xml version="1.0"?>
<urlset>
    <url>
        <loc>https://www.webdevsplanet.com</loc>
        <lastmod>2023-12-16</lastmod>
        <changefreq>monthly</changefreq>
        <priority>1.0</priority>
    </url>
</urlset>

In this example, we created a new SimpleXMLElement object with a root element ('urlset') by passing a string with opening and closing tags (<urlset></urlset>) to it. Using the addChild() function, added a child element, "url," to it. In the same way, we then added four more child elements ("loc", "lastmod", "changefreq", and "priority") to the "url" element and lastly saved the resulting XML to a file named 'sitemap.xml' in the same directory as the PHP script using the asXML() function. If the file does not exist, it's automatically created. Otherwise, the existing file with that name is overwritten.

When creating a child element, you can pass one or two string arguments to the  addChild() function. The first one is the element name and the second (optional) is its content.

Example 2

<?php
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset></urlset>');
$xml->addAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9");
$url = $xml->addChild("url");
$url->addChild("loc", "https://www.webdevsplanet.com");
$url->addChild("lastmod", "2023-12-16");
$xml->asXML("sitemap.xml");
?>

Output: A file named "sitemap.xml" with the code below.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>https://www.webdevsplanet.com</loc>
        <lastmod>2023-12-16</lastmod>
    </url>
</urlset>

In the above example, we have specified the encoding type when creating a new SimpleXMLElement object and also added an attribute to the urlset element using the addAttribute() function.

Dynamic Generation with Data from Database

To add multiple child elements at once from database records to the SimpleXMLElement object, we can do that through a loop. For instance, let's say you have a blog posts table in a MySQL database with the URLs and the last updated date fields. You can easily add them as below.

<?php
// Creating a SimpleXMLElement object and adding an attribute to it
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset></urlset>');
$xml->addAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9");

// Establishing a database connection
$conn = mysqli_connect($servername, $username, $password, $dbname);

// Selecting url and last update date from all table records
$query = "SELECT url, updated_at FROM blog_posts";

// Executing the SQL query
$result = mysqli_query($conn, $query);

// Looping through all rows
while ($row = mysqli_fetch_assoc($result)) {
    // Addiing a child element ('url') to the XML object
    $url = $xml->addChild("url");

    /*
    * Adding two child elements ('loc' and 'loc')
    * with their values (from database) to the 'url' element
    */
    $url->addChild("loc", $row["url"]);
    $url->addChild("lastmod", $row["updated_at"]);
}

// Save the XML to a file
$xml->asXML("sitemap.xml");
?>

Output: A file named "sitemap.xml" with the code below.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://www.example.com/first-page</loc>
    <lastmod>2023-12-14</lastmod>
  </url>
  <url>
    <loc>https://www.example.com/second-page</loc>
    <lastmod>2023-12-16</lastmod>
  </url>
  <url>
    <loc>https://www.example.com/third-page</loc>
    <lastmod>2023-12-16</lastmod>
  </url>
  <!-- More page URLs... -->
</urlset>

This way, you can trigger this code to run every time you add a blog post or make changes to an existing post and the XML sitemap will always be up-to-date with new URLs and last modified dates.

Dynamic Generation with Data from an Array

If you have data in an array of associative arrays, you can generate a SimpleXML object in the same approach as from the database above, only that this time you don't have to query from a database and use the foreach() loop instead.

Example

<?php
$pages = array(
        ["url" => "https://www.example.com/first-page", "updated_at" => "2023-12-14"],
        ["url" => "https://www.example.com/second-page", "updated_at" => "2023-12-16"],
        ["url" => "https://www.example.com/third-page", "updated_at" => "2023-12-16"]
);

$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset></urlset>');
$xml->addAttribute("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9");

foreach ($pages as $page) {
    $url = $xml->addChild("url");
    $url->addChild("loc", $page["url"]);
    $url->addChild("lastmod", $page["updated_at"]);
}

$xml->asXML("sitemap.xml");
?>

Output: A file named "sitemap.xml" with the code below.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>https://www.example.com/first-page</loc>
        <lastmod>2023-12-14</lastmod>
    </url>
    <url>
        <loc>https://www.example.com/second-page</loc>
        <lastmod>2023-12-16</lastmod>
    </url>
    <url>
        <loc>https://www.example.com/third-page</loc>
        <lastmod>2023-12-16</lastmod>
    </url>
</urlset>

Updating XML Content

When manipulating an existing XML file, you don't need to create a new SimpleXMLElement object but should instead load it using the simplexml_load_file() function.

Example

<?php
// Loading an existing XML file
$xml = simplexml_load_file("sitemap.xml");

// SimpleXML methods and PHP code for manipulation
// ...

Make sure to include the right file path if the XML file is not located in the same directory as the PHP script.

When you want to read or modify XML in a string, use the simplexml_load_string() function instead. In this case, you pass the string variable as the argument.

Example

<?php
// Converting an XML string into an object
$xml = simplexml_load_string($xmlVariable);

// SimpleXML methods and PHP code for manipulation
// ...

You can do all sorts of modifications such as adding child elements, updating the content of elements, adding attributes to elements or updating their values, etc.

Example

<?php
$student = <<<XML
<student>
    <name>John Doe</name>
    <age>21</age>
    <course>Computer Science</course>
</student>
XML;

$xml = simplexml_load_string($student);
$xml->addAttribute("id", 241);
$xml->name = "Rajesh Kumar";
$xml->addChild("email", "rajesh@gmail.com");
Header('Content-type: text/xml');
echo $xml->asXML();
?>

Output:
<student id="241">
   <name>Rajesh Kumar</name>
   <age>21</age>
   <course>Computer Science</course>
   <email>rajesh@gmail.com</email>
</student>

In this example, we converted an XML string in a variable to a SimpleXML object, added an attribute to the root element ('student'), updated the student name from 'John Doe' to 'Rajesh Kumar', added a new child element ('email') with its value as 'rajesh@gmail.com', and printed the resulting XML.

Updating XML content in an existing file or string is as easy as that.

Creating XML files in PHP with custom code

Besides using specialized built-in XML extensions such as SimpleXML, XML DOM Parser, XMLWriter, etc, you can also do it in your custom ways.

Example

<?php
$pages = array(
        ["url" => "https://www.example.com/first-page", "updated_at" => "2023-12-14"],
        ["url" => "https://www.example.com/second-page", "updated_at" => "2023-12-16"],
        ["url" => "https://www.example.com/third-page", "updated_at" => "2023-12-16"]
);

$sitemap = '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
';

foreach ($pages as $page) {
$sitemap .= '<url>
  <loc>'.$page["url"].'</loc>
  <lastmod>'.$page["updated_at"].'</lastmod>
</url>
';
}
$sitemap .= '</urlset>';
file_put_contents('sitemap.xml',$sitemap);
?>

Output: A file named "sitemap.xml" with the code below.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
  <loc>https://www.example.com/first-page</loc>
  <lastmod>2023-12-14</lastmod>
</url>
<url>
  <loc>https://www.example.com/second-page</loc>
  <lastmod>2023-12-16</lastmod>
</url>
<url>
  <loc>https://www.example.com/third-page</loc>
  <lastmod>2023-12-16</lastmod>
</url>
</urlset>

In this example, we have used the strings concatenation method where we have generated various parts separately and then joined them together. We then used the file_put_contents() function to write the XML string's contents into a file.

If the filename name specified in this function does not exist, the file is created automatically. Otherwise, the existing file is overwritten.

That's it!

By going through this article, you can easily generate and manipulate XML files using PHP.