0

I'm simply wanting to add cdata to an xml node - description. My xml function is below. I have tried using bits of the following function on php.net in my function

<?php
function updateXMLFile($itemName, $description, $pageName, $imageFileName)
{
  $imageSrc         = "<img src='http://nicolaelvin.com/authoring/phpThumb/phpThumb.php?src=../images/" . $imageFileName . "&w=100'/>";
  $id               = strtolower($id = str_replace(' ', '_', $itemName));
  $directLinkToItem = 'http://nicolaelvin.com/authoring/' . $pageName . '.php#' . $id;

  $xml  = simplexml_load_file('nicolaElvinsPortfolio.xml');
  $item = $xml->channel->addChild('item');
  $item->addChild('title', $itemName);

  $item->addChild('pubDate', date('r'));
  $item->addChild('link', $directLinkToItem);
  $item->addChild('description');
  $cdata->description->createCDATASection('testyfhgjhsgsdjahgs');
  $item->appendChild($cdata);

  ///Format XML to save indented tree rather than one line
  $dom                     = new DOMDocument('1.0');
  $dom->preserveWhiteSpace = false;
  $dom->formatOutput       = true;
  $dom->loadXML($xml->asXML());

  //Save XML to file - remove this and following line if save not desired
  $dom->save('nicolaElvinsPortfolio.xml');

}

//function from php.net
function sxml_cdata($path, $string)
{
  $dom   = dom_import_simplexml($path);
  $cdata = $dom->ownerDocument->createCDATASection($string);
  $dom->appendChild($cdata);
}
?>

current xml document tree, just want to a cdata in the description tags

quantme
  • 3,609
  • 4
  • 34
  • 49
Claire
  • 3,683
  • 13
  • 47
  • 74
  • I have tried the bit in it that says create CDATASection which I adapted from the function from php.net. I don't get any errors, it just doesn't add anything to my XML document. – Claire May 04 '12 at 09:00
  • I'm not sure simpleXML supports that functionality. As its name suggests it's for simple manipulations of XML. You might have to resort to the full DOM classes. – GordonM May 04 '12 at 09:21
  • oh, ok thanks , I'm not sure how to do that so I may have to leave it out – Claire May 04 '12 at 09:21
  • Are you sure don't get any errors? Specifically are you sure you don't get an E_FATAL along the lines of `Attempt to call method 'createCDATASection()' on a non-object`? The reason I ask is that you never define `$cdata` in the scope of the `updateXMLFile()` function... – DaveRandom May 04 '12 at 09:24
  • no, I don't know where the error would be. I new to XML. But when I call the function there's no errors on the browser window or in the console. Is there a way to output errors with xml? – Claire May 04 '12 at 09:27
  • Try simply placing `ini_set('display_errors', 1); error_reporting(E_ALL);` at the top of your script... – DaveRandom May 04 '12 at 09:28
  • I have to say that looking at your code, you should probably just do all of it with DOM. SimpleXML is exactly what the name suggests - simple. It does not support many of the advanced (or even not so advanced) features like CDATA, DOM document can do anything that SimpleXML can do, and much more. Especially since you pass it DOM at the end anyway... – DaveRandom May 04 '12 at 09:30
  • ooooh now I have: Fatal error: Call to undefined method SimpleXMLElement::createCDATASection() in /var/www/vhosts/nicolaelvin.com/httpdocs/authoring/includes/functions.php on line 22 – Claire May 04 '12 at 09:31
  • ok, can you point me to a tutorial on how to do it as a dom? – Claire May 04 '12 at 09:32
  • I've added $dom->loadXML($xml->asXML()); $item=$dom->getElementsByTagName('description'); $item->createCDATASection('testyfhgjhsgsdjahgs'); to the bottom of my function to try and manipulate the dom object – Claire May 04 '12 at 09:39
  • Hang on, let me properly walk through the code and work out how to convert it to DOM. – DaveRandom May 04 '12 at 09:43
  • do you want a screenshot of the dom tree? – Claire May 04 '12 at 09:44
  • Would be helpful to have a before and after of the document, also what does the `$desciption` argument to the `updateXMLFile()` function do? You don't appear to use it anywhere... – DaveRandom May 04 '12 at 09:51
  • EDIT description is where I am hoping to add in the CDATA , and then put $description in there along with $imageSrc so I can add an image in there, I'll add a screenshot of the tree to my question – Claire May 04 '12 at 09:53
  • Cool, give me half an hour, I'm a bit busy at work :-) – DaveRandom May 04 '12 at 10:15
  • 1
    See if this works - http://www.php.net/manual/en/simplexmlelement.addchild.php#104458 or this - http://stackoverflow.com/questions/6260224/how-to-write-cdata-using-simplexmlelement – web-nomad May 04 '12 at 10:53

1 Answers1

1

Try this on for size. Let me know if you have any problems with it/questions about it (FIXED).

function updateXMLFile($itemName, $description, $pageName, $imageFileName) {

  // Path to file that will be used
  $filePath = 'nicolaElvinsPortfolio.xml';

  // Create links - don't forget to escape values appropriately with urlencode(), htmlspecialchars() etc
  $imageSrc = "<img src='".htmlspecialchars('http://nicolaelvin.com/authoring/phpThumb/phpThumb.php?src=../images/'.urlencode($imageFileName).'&w=100')."'/>";
  $directLinkToItem = 'http://nicolaelvin.com/authoring/'.urlencode($pageName).'.php#'.urlencode(strtolower(str_replace(' ', '_', $itemName)));

  // Create the CDATA value - whatever you want this to look like
  $cdata = "$description: $imageSrc";

  // Create a DOMDocument
  $dom = new DOMDocument('1.0');
  $dom->preserveWhiteSpace = false;
  $dom->formatOutput = true;

  // Load data from file into DOMDocument
  if (!$dom->load($filePath)) throw new Exception("Unable to load data source file '$filePath'");

  // Create the new <item> and add it to the document
  $item = $dom->getElementsByTagName('channel')->item(0)->appendChild(new DOMElement('item'));

  // Add the <item>'s sub elements
  $item->appendChild(new DOMElement('title', $itemName));
  $item->appendChild(new DOMElement('pubDate', date('r')));
  $item->appendChild(new DOMElement('link', $directLinkToItem));

  // Add the CDATA
  $item->appendChild(new DOMElement('description'))->appendChild(new DOMCdataSection($cdata));

  // Now save back to file
  $dom->save($filePath);

}

N.B. this now throws an exception if DOMDocument::load() fails - don't forget to catch it!

DaveRandom
  • 87,921
  • 11
  • 154
  • 174