Page 1 of 1

getting file_get_contents to display contents of an XML file

Posted: Wed Jun 24, 2009 10:20 pm
by tempomental
Hey all,

Much appreciation in advance for any help received.

I'm writing a simple page that retrieves data in XML format and displays it as a table. I've been using HTML/JS successfully for testing on my own machine, but once I get it onto the production server I get 304 errors in Apache and an Access denied error in my HttpXML "GET" statement. I e-mailed my admin and asked for some pointers, and he said that the issue is cross-site scripting. My page is attempting to access content on a different website, and thus is failing. I need to move the GET request to a URL on your website. That GET request should hit a server-side script that returns the XML content from the database (via, for instance, a PHP file_get_contents() or a CURL command).

My question is: how do I do this? I'm learning PHP as-I-go here, but can't spend any more time learning -- I need to have something coded fast.

Some things: My request for the data is being passed through URL, so there are some ?= and &= parameters in there. I could pass the parameters through XML, but I don't quite understand how to do that (steep learning curve with zero time, unfortunately). I've tried using $_GET to reconstruct the URL in the PHP file for the file_get_contents(), but it doesn't seem to be working: my PHP code doesn't output anything.

So again, HTML file (with various inputs) calls PHP file, needing to pass parameters to generate the URL for the query. PHP file takes URL and returns XML. HTML file receives XML and displays it as a nice table.

Thanks for your help!

-tempomental-

Re: getting file_get_contents to display contents of an XML

Posted: Thu Jun 25, 2009 12:38 pm
by McInfo
This is an example of one possible solution: using XSLT to format the XML.

Assume there is a remote server (192.168.0.2) that hosts an XML file.

Remote Server

options.dtd - The document type definition is hosted on the remote server.

Code: Select all

<!ELEMENT options (option+)>
    <!ELEMENT option (name, value)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT value (#PCDATA)>
remote.xml.php - The XML file displays a list of options and allows you to add an extra option to the list by passing a name and value to the script.

Code: Select all

<?php
$name  = null;
$value = null;
if (isset($_GET['name'], $_GET['value'])) {
    $name  = preg_replace('/[^a-zA-Z0-9]/', '', $_GET['name']);
    $value = preg_replace('/[^a-zA-Z0-9]/', '', $_GET['value']);
}
header('Content-Type: text/xml');
echo '<?xml version="1.0" encoding="UTF-8" ?>'."\n";
?>
<!DOCTYPE options SYSTEM "options.dtd">
<options>
    <option>
        <name>color</name>
        <value>red</value>
    </option>
    <option>
        <name>shape</name>
        <value>rectangle</value>
    </option>
    <option>
        <name>width</name>
        <value>300px</value>
    </option>
<?php if (!is_null($name) && !is_null($value)) : ?>
    <option>
        <name><?php echo $name; ?></name>
        <value><?php echo $value; ?></value>
    </option>
<?php endif; ?>
</options>
Local Server

transform.xsl - To display the XML data in a table, you can use XSLT. This file is called indirectly through the XML file, just as a linked CSS file would be called by an HTML file.

Code: Select all

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/options">
        <html>
            <head>
                <title>Options</title>
                <link rel="stylesheet" type="text/css" href="style.css" />
            </head>
            <body>
                <h1>Options</h1>
                <table cellspacing="1">
                    <thead>
                        <tr>
                            <th scope="col">Name</th>
                            <th scope="col">Value</th>
                        </tr>
                    </thead>
                    <tbody>
                        <xsl:for-each select="option">
                            <tr>
                                <td><xsl:value-of select="name" /></td>
                                <td><xsl:value-of select="value" /></td>
                            </tr>
                        </xsl:for-each>
                    </tbody>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>
style.css - This CSS file makes the table look better.

Code: Select all

@CHARSET "UTF-8";
table { background-color: #CCC; }
th, td { padding: .25em; }
th { background-color: #EEE; }
td { background-color: #FFF; }
local.xml.php - This script gets the remote XML file as a string. An extra option will be added to the options list returned by the remote server because the two arguments "name=Hello" and "value=World" are passed in the URL. The script inserts a reference to the XSL file into the XML, which allows the XML to be viewed as an HTML table.

Code: Select all

<?php
// The path to the remote XML file
$remote_url = 'http://192.168.0.2/remote.xml.php?name=Hello&value=World';
 
// Gets the remote XML file
$xml = file_get_contents($remote_url);
 
// The new stylesheet that will turn this XML into an HTML table
$stylesheet = '<?xml-stylesheet type="text/xsl" href="transform.xsl" ?>';
 
// Finds and replaces an existing stylesheet reference
if (strpos($xml, '<?xml-stylesheet', 0)) {
    $xml = preg_replace('/<\?xml-stylesheet[^>]*>/', $stylesheet, $xml, 1);
}
// ...or finds the doctype and appends a stylesheet reference
elseif (strpos($xml, '<!DOCTYPE', 0)) {
    $xml = preg_replace('/<!DOCTYPE[^>]*>/', '\0'."\n".$stylesheet, $xml, 1);
}
 
// Outputs the XML
header('Content-Type: text/xml');
echo $xml;
?>
Edit: This post was recovered from search engine cache.