Wednesday, 7 April 2010

<?xml version="1.0"?> Removal using PHP

I've been working on something for ages which involved creating some XML formatted data using PHP. PHPs implementation of XML has come on leaps and bounds, it seems, and I must admit to being pretty happy with the results using PHPs DOM implementation. So I uploaded the XML to its target API and nothing happened. And nothing kept happening, over and over again...

After a fair bit of head-scratching and trying any number of things. I tried to see if the XML was broken somehow and managed to run foul of trying to print an XML Object before converting it to a string with saveXML()... oops! Then I thought about the XML Prolog and how the examples of using the API I'd seen hadn't had the whole <?xml version="1.0"?> at the beginning of the XML. Now how was a going to get rid of it?

At first I just echoed the XML to a browser and copied the resultant XML into Boxer (and sure, who wouldn't use Boxer with it's lovely Format XML tool?). Then I removed the Prolog and copied it into a string variable using the "here document" syntax and tried to upload that and all worked well. A bit clunky but it worked!.

How to remove the Prolog programmatically though?

I got to thinking about my initial fascination with XML and the stuff I read in 2004 or so and remembered XSL. PHP can use XSL so I did a bit of research and came up with this XSL file:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes"/>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Then it was a simple matter to put the following in the script:

  // Load XML file
  $xsl = new DOMDocument;
  $xsl->load('removeProlog.xsl', LIBXML_NOCDATA);

  // Configure the transformer
  $proc = new XSLTProcessor;
  // and attach the xsl rules
  $proc->importStyleSheet($xsl); 

  // Replace the XML with the transformed XML
  $xml = $proc->transformToXML($xml);

Hey Presto, all done and my hair can get back to growing ;-)