PHP XML Help needed

Thor

Honorary Master
Joined
Jun 5, 2014
Messages
44,413
Reaction score
7,522
Location
Bellville
Hello,

How do I write to an XML file (in that specific format?)

This is the XML file I want to make:

PHP:
<?xml version="1.0" encoding="iso-8859-1"?>
<articles>
  <article>
    <header>{{Article heading}}</header>
    <description>{{Article description}}</description>
    <date>{{Article date}}</date>
    <link>{{Article url}}</link>
  </article>
</articles>

I want to scan my RSS feed and then write to my XML file (I know how to save it using the domelement. I want to know how to place the content in that format of the xml above also I must be able to append to the XML file as it will grow as I get info more articles.)

I have the variables already $header, $description $date and $link just need to get them into the XML file.

Hope it makes sense.
 
Last edited:
formatOutput = true;?

https://secure.php.net/manual/en/domdocument.savexml.php
PHP:
<?php

$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;

$root = $doc->createElement('book');
$root = $doc->appendChild($root);

$title = $doc->createElement('title');
$title = $root->appendChild($title);

$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);

echo "Saving all the document:\n";
echo $doc->saveXML() . "\n";

echo "Saving only the title part:\n";
echo $doc->saveXML($title);

?>
From: https://secure.php.net/manual/en/domdocument.savexml.php

Output:
PHP:
Saving all the document:
<?xml version="1.0"?>
<book>
  <title>This is the title</title>
</book>

Saving only the title part:
<title>This is the title</title>

EDIT:
PHP:
$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;

$root = $doc->createElement('articles');
$root = $doc->appendChild($root);

$article= $doc->createElement('article');
$article= $root->appendChild($article);

$header= $doc->createElement('header');
$header= $article->appendChild($header);

$text = $doc->createTextNode('{{Article heading}}'); //assuming you want this to rather be the variable?
$text = $title->appendChild($text);

$description = $doc->createElement('description');
$description = $article->appendChild($description);

$text = $doc->createTextNode('{{Article description}}'); //assuming you want this to rather be the variable?
$text = $description->appendChild($text);

$date = $doc->createElement('date');
$date = $article->appendChild($date);

$text = $doc->createTextNode('{{Article date}}'); //assuming you want this to rather be the variable?
$text = $date->appendChild($text);

$link = $doc->createElement('link');
$link = $article->appendChild($link);

$text = $doc->createTextNode('{{Article url}}'); //assuming you want this to rather be the variable?
$text = $link->appendChild($text);

$doc->saveXML();

As a base, copy pasted variable names, just edit. Never worked with XML+PHP, just from what I've gathered reading the comments. Hope someone else can give a working answer if mine is wrong.

EDIT: Wait, you need to append to the correct var
 
Last edited:
formatOutput = true;?

https://secure.php.net/manual/en/domdocument.savexml.php
PHP:
<?php

$doc = new DOMDocument('1.0');
// we want a nice output
$doc->formatOutput = true;

$root = $doc->createElement('book');
$root = $doc->appendChild($root);

$title = $doc->createElement('title');
$title = $root->appendChild($title);

$text = $doc->createTextNode('This is the title');
$text = $title->appendChild($text);

echo "Saving all the document:\n";
echo $doc->saveXML() . "\n";

echo "Saving only the title part:\n";
echo $doc->saveXML($title);

?>
From: https://secure.php.net/manual/en/domdocument.savexml.php

Output:
PHP:
Saving all the document:
<?xml version="1.0"?>
<book>
  <title>This is the title</title>
</book>

Saving only the title part:
<title>This is the title</title>
Thanks for this, let me play around, does this add to the xml file?

I saw this example, but I don't understand how the append work ie I don't want that root bit to be duplicated if that makes sense.

I just want to add more articles to my xml file as my feed grows, currently I update the xml file myself.
 
Thanks for this, let me play around, does this add to the xml file?

I saw this example, but I don't understand how the append work ie I don't want that root bit to be duplicated if that makes sense.

I just want to add more articles to my xml file as my feed grows, currently I update the xml file myself.

Yeah, just refer to the correct parent. So I changed the variable names, should make it a bit easier to understand. You need to add $dom->load ("test.xml"); which points to the correct place. Use the variable name to append to the correct variable, so if e.g. header is child of article, use $article->appendChild($header); that you created. I edited the variables, hopefully that will work.

EDIT: Oh I see, the root element is closed once complete.

https://stackoverflow.com/questions/15201433/adding-a-new-node-in-xml-file-via-php
Suggests
I'd use SimpleXML for this. It would look somehow like this:
PHP:
// Open and parse the XML file
$xml = simplexml_load_file("questions.xml");
// Create a child in the first topic node
$child = $xml->topic[0]->addChild("subtopic");
// Add the text attribute
$child->addAttribute("text", "geography");
You can either display the new XML code with echo or store it in a file.
PHP:
// Display the new XML code
echo $xml->asXML();
// Store new XML code in questions.xml
$xml->asXML("questions.xml");

With the PHP SimpleXML having a nice recursive function: http://be2.php.net/manual/en/book.simplexml.php#108688
Here is a recursive function that will convert a given SimpleXMLElement object into an array, preserving namespaces and attributes.
PHP:
<?php
function xmlObjToArr($obj) {
        $namespace = $obj->getDocNamespaces(true);
        $namespace[NULL] = NULL;
       
        $children = array();
        $attributes = array();
        $name = strtolower((string)$obj->getName());
       
        $text = trim((string)$obj);
        if( strlen($text) <= 0 ) {
            $text = NULL;
        }
       
        // get info for all namespaces
        if(is_object($obj)) {
            foreach( $namespace as $ns=>$nsUrl ) {
                // atributes
                $objAttributes = $obj->attributes($ns, true);
                foreach( $objAttributes as $attributeName => $attributeValue ) {
                    $attribName = strtolower(trim((string)$attributeName));
                    $attribVal = trim((string)$attributeValue);
                    if (!empty($ns)) {
                        $attribName = $ns . ':' . $attribName;
                    }
                    $attributes[$attribName] = $attribVal;
                }
               
                // children
                $objChildren = $obj->children($ns, true);
                foreach( $objChildren as $childName=>$child ) {
                    $childName = strtolower((string)$childName);
                    if( !empty($ns) ) {
                        $childName = $ns.':'.$childName;
                    }
                    $children[$childName][] = xmlObjToArr($child);
                }
            }
        }
       
        return array(
            'name'=>$name,
            'text'=>$text,
            'attributes'=>$attributes,
            'children'=>$children
        );
    }
?>
 
Last edited:
I love you, thanks for the time.

I'm on way home, when I get there I will test it out and report back.
 
Where do I say where the file needs to be saved too?

The current XML file is in /articles/index.xml
 
Okay that works as in it writes the document, but it doesn't append if I put it in the loop then it simply overwrites the XML file.

I loaded the RSS feed with 50 articles it overwrites the XML file on each saves instead of appending.
 
Boom fixed it!


PHP:
                foreach ($feed as $item) { //50 articles to loop
                  $title = $item['title'];
                  $desc = $item['desc'];
                  $datep = $item['date'];
                  $url = $item['link'];
                  
                  $xml = simplexml_load_file('articles/index.xml');

                  $articles = $xml->articles;
                  
                  $article = $xml->addChild('article');
                  $article->addChild('header', $title);
                  $article->addChild('description', $desc);
                  $article->addChild('date', $datep);
                  $article->addChild('url', $url);
              
                  $xml->asXML('articles/index.xml'); // It saved all 50! yay!
                  
               /*$doc = new DOMDocument('1.0');
                  // we want a nice output
                  $doc->formatOutput = true;

                  $root = $doc->createElement('articles');
                  $root = $doc->appendChild($root);

                  $article= $doc->createElement('article');
                  $article= $root->appendChild($article);

                  $header= $doc->createElement('header');
                  $header= $article->appendChild($header);

                  $text = $doc->createTextNode($title); //assuming you want this to rather be the variable?
                  $text = $header->appendChild($text);

                  $description = $doc->createElement('description');
                  $description = $article->appendChild($description);

                  $text = $doc->createTextNode($desc); //assuming you want this to rather be the variable?
                  $text = $description->appendChild($text);

                  $date = $doc->createElement('date');
                  $date = $article->appendChild($date);

                  $text = $doc->createTextNode($datep); //assuming you want this to rather be the variable?
                  $text = $date->appendChild($text);

                  $link = $doc->createElement('link');
                  $link = $article->appendChild($link);

                  $text = $doc->createTextNode($url); //assuming you want this to rather be the variable?
                  $text = $link->appendChild($text);

                  echo $doc->saveXML();
                  $doc->save('articles/index.xml');*/ 
                }
                ?>
 
Top
Sign up to the MyBroadband newsletter
X