2

I try to build a simple chatbot in HTML/PHP/XML. The 'brain' is build in XML. A html form will be submitted through AJAX which makes a call to searchBrain.php. The problem is, when is submit the form, searchBrain does not query my brain.xml file. Can someone offer me some help?

brain.xml

<?xml version="1.0" encoding="UTF-8"?>
<brain>
    <neuron>
        <id>1</id>
        <input>wie ben jij?</input>
        <code></code>
        <output>Ik ben Skye</output>
        <keywords>wie,ben,jij,Wie,?</keywords>
        <image></image>
    </neuron>
    <neuron>
        <id>2</id>
        <input>hoe gaat het?</input>
        <code></code>
        <output>Met mij gaat het goed. Hoe gaat het me u?</output>
        <keywords>hoe,gaat,het,Hoe,?</keywords>
        <image></image>
    </neuron>
    <neuron>
        <id>3</id>
        <input>wat ben jij?</input>
        <code></code>
        <output>Ik ben het laatste resultaat in kunstmatige intelligentie die de functies van het menselijk brein kan reproduceren met een grotere snelheid en nauwkeurigheid.</output>
        <keywords>wat,ben,jij,Wat,?</keywords>
        <image></image>
    </neuron>
    <neuron>
        <id>4</id>
        <input>hoe zie jij er uit?</input>
        <code></code>
        <output></output>
        <keywords>hoe,zie,jij,er,uit,Hoe,?</keywords>
        <image><!-- insert binary.jpg from imgLib --></image>
    </neuron>
    <neuron>
        <id>5</id>
        <input>stel jezelf even voor</input>
        <code></code>
        <output>Hoi ik ben Skye, ik ben online gegaan op 17-02-2016.Ik ben het laatste resultaat in kunstmatige intelligentie die de functies van het menselijk brein kan reproduceren met een grotere snelheid en nauwkeurigheid.</output>
        <keywords>stel,jezelf,even,voor</keywords>
        <image></image>
    </neuron>
    <neuron>
        <id>6</id>
        <input>Welke dag is het vandaag?</input>
        <code><!-- PHP code om huidige dag weer te geven --></code>
        <output>Vandaag is het </output>
        <keywords>welke,dag,is,het,vandaag,?</keywords>
        <image></image>
    </neuron>
    <neuron>
        <id>7</id>
        <input>wanneer ben je jarig?</input>
        <code></code>
        <output>Ik ben online gegaan op 17 Februari, dus ik ben jarig op 17 Februari :-)</output>
        <keywords>wanneer,ben,je,jarig,?</keywords>
        <image><!-- jarig.jpeg from imgLib --></image>
    </neuron>
</brain>

searchBrain.php

<?php 

    //Create DOMDocument based on XML
    $dom = new DOMDocument();

    // We don't want to bother with white spaces
    $dom->preserveWhiteSpace = false;

    //Load brain.xml
    $dom->Load('brain.xml');

    //Get POST value
    $sentence = $_POST['sentence'];

    //Lowercase the XML so non case sensitive search is possible
    $xml = strtolower($xml);

    //Create XPath based on the DOM Document to search it
    $xpath = new DOMXpath($dom);

    //Define keywords for search
    $searchKeywords = array($sentence);

    //Iterate all of them to make them into valid XPath
    $searchKeywords = array_map(
    function($keyword){
        //Replace any single quotes with an escaped single quote
        $keyword = str_replace('\'','\\\'',$keyword);
        return 'contains(.,\''.$keyword.'\')';
    },
    $searchKeywords
    );

    //Implode all the keywords using and, could 
    //be changed to be an "or" condition if needed
    $searchKeywords = implode(' and ',$searchKeywords);

    //The search keywords now look like contains(.,'good') and
    //contains(.,'hello')

    //Search for any neuron tag that contains the text
    //submitted by the from
    $nodes = $xpath->query('//keywords['.$searchKeywords.']');

    //Iterate all nodes
    foreach($nodes as $node){
        //Find the output node an print its content
        var_dump($xpath->query('output',$node)->item[3]->textContent);
    }

?>

And the index.php

<!DOCTYPE html>
<head>
    <title>Skye</title>
    <script src="jquery-2.1.4.js"></script>

    <script>
    $(document).ready(function() {
        $("#Skye").submit(function(e){
            var url = "searchBrain.php";

            $.ajax({
                type: "POST",
                url: url,
                data: $("#Skye").serialize(),
                success: function(response){
                    $("#result").html(response); 
                    //alert(response);
                }
            });
            e.preventDefault();
        });
    });
    </script>

    <link rel="stylesheet" type="text/css" href="gui/css/skye.css" />
</head>
<body>

    <h1>Skye</h1>

    <div id="result"></div>

    <form id="Skye" name="Skye" method="POST" >
        <input type="text" id="sentence" name="sentence" autofocus="autofocus" />
        <input type="submit" id="display" value="Stuur..." />
    </form>



</body>
</html>
WouterPoel
  • 33
  • 2
  • I don't think this is the cause of your issue but Undefined variable: xml - $xml = strtolower($xml); – Matt in Washington Feb 16 '16 at 21:33
  • *btw* Here is no escaping for quotes in XPath 1. Here is an example for a function that solves the problem http://stackoverflow.com/a/27440520/2265374 – ThW Feb 17 '16 at 09:47
  • @MattinWashington thank you i missed that one. ThW, thank you! i will look in to it. – WouterPoel Feb 17 '16 at 10:02
  • Unrelated, but here you have a hassle-free approach: http://fsockopen.com/php-programming/your-final-stop-for-php-xpath-case-insensitive – Chris Russo Aug 17 '16 at 04:05

1 Answers1

2

Well I found a problem with your query. If you are looking for exact matches and want the parent node you need this:

$nodes = $xpath->query('//neuron/keywords[contains(text(), "wanneer") and contains(text(), "gaat")]/..');

so you would replace implode(' and ', $searchKeywords) with the above.

You can also shorthand the above syntax like so as per a commentator below:

$nodes = $xpath->query('//neuron[keywords[contains(., "wanneer") or contains(., "gaat")]]');

What does it do?

Well it looks at every neuron then searches if the text value of <keywords> has what you're looking for and the /.. is like a filepath that basically returns the parent. Pretty nifty. Now you can get the <output> tag.

//Iterate all nodes
foreach($nodes as $node){
    //Find the output node an print its content
    var_dump($xpath->query('output',$node)->item(0)->textContent);
}

Here is my code in full that I tested with. You can copy paste this in a test file to see the results and tinker so that you can adopt it to your script.

<?php

$xml = xml_str();
$dom = new DOMDocument();
$dom->loadXML($xml);

$xpath= new DOMXPath($dom);
$nodes = $xpath->query('//neuron/keywords[contains(text(), "wanneer") or contains(text(), "gaat")]/..');

foreach ($nodes as $node) {
    var_dump($xpath->query('output', $node)->item(0)->textContent);
}

function xml_str()
{
    return <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<brain>
    <neuron>
        <id>1</id>
        <input>wie ben jij?</input>
        <code></code>
        <output>Ik ben Skye</output>
        <keywords>wie,ben,jij,Wie,?</keywords>
        <image></image>
    </neuron>
    <neuron>
        <id>2</id>
        <input>hoe gaat het?</input>
        <code></code>
        <output>Met mij gaat het goed. Hoe gaat het me u?</output>
        <keywords>hoe,gaat,het,Hoe,?</keywords>
        <image></image>
    </neuron>
    <neuron>
        <id>3</id>
        <input>wat ben jij?</input>
        <code></code>
        <output>Ik ben het laatste resultaat in kunstmatige intelligentie die de functies van het menselijk brein kan reproduceren met een grotere snelheid en nauwkeurigheid.</output>
        <keywords>wat,ben,jij,Wat,?</keywords>
        <image></image>
    </neuron>
    <neuron>
        <id>4</id>
        <input>hoe zie jij er uit?</input>
        <code></code>
        <output></output>
        <keywords>hoe,zie,jij,er,uit,Hoe,?</keywords>
        <image><!-- insert binary.jpg from imgLib --></image>
    </neuron>
    <neuron>
        <id>5</id>
        <input>stel jezelf even voor</input>
        <code></code>
        <output>Hoi ik ben Skye, ik ben online gegaan op 17-02-2016.Ik ben het laatste resultaat in kunstmatige intelligentie die de functies van het menselijk brein kan reproduceren met een grotere snelheid en nauwkeurigheid.</output>
        <keywords>stel,jezelf,even,voor</keywords>
        <image></image>
    </neuron>
    <neuron>
        <id>6</id>
        <input>Welke dag is het vandaag?</input>
        <code><!-- PHP code om huidige dag weer te geven --></code>
        <output>Vandaag is het </output>
        <keywords>welke,dag,is,het,vandaag,?</keywords>
        <image></image>
    </neuron>
    <neuron>
        <id>7</id>
        <input>wanneer ben je jarig?</input>
        <code></code>
        <output>Ik ben online gegaan op 17 Februari, dus ik ben jarig op 17 Februari :-)</output>
        <keywords>wanneer,ben,je,jarig,?</keywords>
        <image><!-- jarig.jpeg from imgLib --></image>
    </neuron>
</brain>
XML;
}
?>
Paul Carlton
  • 2,785
  • 2
  • 24
  • 42