Home > Software engineering >  Restrict XML data from an HTML form using PHP and XSL
Restrict XML data from an HTML form using PHP and XSL

Time:03-30

I've created a table from XML data with all the Oscar nominees (holding various info) using XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Oscars">
    <html>
        <head>
            <style>
                th { text-align: left; }
            </style>
            <title>Oscars</title>
        </head>
        <body>
            <table  width="65%">
                <tr><th>Year</th><th>Category</th><th>Nominee</th><th>Info</th><th>Won</th></tr>
                <xsl:for-each select="Nomination">
                    <tr>
                        <td><xsl:value-of select="Year"/></td>
                        <td><xsl:value-of select="Category"/></td>
                        <td><xsl:value-of select="Nominee"/></td>
                        <td><xsl:value-of select="Info"/></td>
                        <td><xsl:value-of select="Won"/></td>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>
</xsl:stylesheet>

The output is a table with thousands of lines. I have created a very basic HTML form that the user can filter this table, and using PHP, I need to show only the rows that match the criteria.

That's what I did so far in the PHP file, not sure if POST is the right option here, but I don't think it makes a difference. I have no idea how to make the connection here. I'm super new to PHP and I'm really struggling to get the grasp of this.

<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("oscars.xml");
$xslDoc = new DOMDocument();
$xslDoc->load("oscars.xsl");
$proc = new XSLTProcessor();
$xslDoc = $proc->importStylesheet($xslDoc);
$htmlDoc = $proc->transformToDoc($xmlDoc);
print $htmlDoc->saveXML();
?>

<html lang="eng">
<head><title>Oscars</title></head>
<body>
<h1>
<?php
$year = $_POST['year'];
$category = $_POST['$category'];
$nominee = $_POST['nominee'];
$info = $_POST['info'];

if ($year == '2010') {
_// show all rows from table that match year
}
?>
</h1>
</body>
</html>

CodePudding user response:

I would use this approach:

Make the xslt using the xsl:param and feed those with php.

php:

<?php
$xmlUri      = '/some/path/to/your.xml';
$xslUri      = '/some/path/to/your.xsl';
$xmlDocument = new DOMDocument;
$xslDocument = new DOMDocument;

if ($xmlDocument->load($xmlUri) && $xslDocument->load($xslUri)) {

    $year     = $_POST['year'];
    $category = $_POST['category'];
    $nominee  = $_POST['nominee'];
    $info     = $_POST['info'];
    $xsltProc = new XSLTProcessor();
    $xsltProc->setParam('year', $year);
    $xsltProc->setParam('category', $category);
    $xsltProc->setParam('nominee', $nominee);
    $xsltProc->setParam('info', $info);
    if ($xsltProc->importStyleSheet($xslDocument)) {
        echo $xsltProc->transformToXML($xmlDocument);
    }
}

Your xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:param name="year"/>
  <xsl:param name="category"/>
  <xsl:param name="nominee"/>
  <xsl:param name="info"/>

  <xsl:template match="/Oscars">
    <html>
      <head>
        <style>
          th { text-align: left; }
        </style>
        <title>Oscars</title>
      </head>
      <body>
        <table  width="65%">
          <tr><th>Year</th><th>Category</th><th>Nominee</th><th>Info</th><th>Won</th></tr>
          <xsl:for-each select="Nomination[
                                          Year    [.=$year      or string-length($year)=0] 
                                      and Category[.=$category  or string-length($category)=0]
                                      and Nominee [.=$nominee   or string-length($nominee)=0]
                                      and Info    [.=$info      or string-length($info)=0]
                                      ]">
            <tr>
              <td><xsl:value-of select="Year"/></td>
              <td><xsl:value-of select="Category"/></td>
              <td><xsl:value-of select="Nominee"/></td>
              <td><xsl:value-of select="Info"/></td>
              <td><xsl:value-of select="Won"/></td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

CodePudding user response:

Dynamically generate your xsl transformation

PHP is good at generating xml, XSL is good at filtering and transforming it.

You can use the selector Nomination[year='2010'] to filter your input xml to just <Nomination> nodes where the value of year is 2010. PHP can dynamically generate these selectors.

For example:

<xml version="1.0" encoding="UTF-8">
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Oscars">
    <html>
        <head>
            <style>
                th { text-align: left; }
            </style>
            <title>Oscars</title>
        </head>
        <body>
            <table  width="65%">
                <tr><th>Year</th><th>Category</th><th>Nominee</th><th>Info</th><th>Won</th></tr>
                <xsl:for-each select="Nomination<?php
$year = 2010;
if ($year) {
    print "[year='$year']";
}
?>">
                    <tr>
                        <td><xsl:value-of select="Year"/></td>
                        <td><xsl:value-of select="Category"/></td>
                        <td><xsl:value-of select="Nominee"/></td>
                        <td><xsl:value-of select="Info"/></td>
                        <td><xsl:value-of select="Won"/></td>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>
</xsl:stylesheet>

Put something similar in either a function or its own file, then call it with the appropriate variables from your post, and then use that in your importStylesheet call.

  • Related