Affichage des articles dont le libellé est bindings. Afficher tous les articles
Affichage des articles dont le libellé est bindings. Afficher tous les articles

15/03/2016

Rdf Facile - Afficher les informations récupérées sur AppInventor

[ cet article fait partie de la série RDF FACILE - Mon petit BigData ]

Bien dans les articles précédents, nous avons : 
- mis en place un serveur RDF / Fuseki, qui nous fournit un accès à un endpoint pour effectuer des requêtes Sparql.
- développé une application sous AppInventor pour effectuer une requête sur cet endpoint.
- modifié cette application pour ajouter des informations sur ce serveur

Nous allons maintenant reprendre cette application pour formater différemment les informations qui nous sont retournées,

On va repartir de la dernière version, celle qui permet d'ajouter des informations. On peut la récupérer ici : http://ai2.appinventor.mit.edu/?galleryId=5233374557372416

Dans la version précédente, on avait juste affiché le résultat de la requete dans la zone de texte (entre les deux version, j'avais même inséré une page pour mieux les visualiser), mais ce n'est pas ce que nous voulons, c'est illisible... on va donc reformater le résultat de la requete.

Le résultat qui nous est retourné est au format JSON et ressemble à ça :

{
  "head": {
    "vars": [ "s" , "p" , "o" ]
  } ,
  "results": {
    "bindings": [
      {
        "s": { "type": "uri" , "value": "http://example.org/dog1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/cat" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/zoo/host" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/2000/01/rdf-schema#range" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/zoo1" } ,
        "p": { "type": "uri" , "value": "http://example.org/zoo/host" } ,
        "o": { "type": "uri" , "value": "http://example.org/cat2" }
      } ,
     ...
      {
        "s": { "type": "uri" , "value": "http://example.org/LucileP" } ,
        "p": { "type": "uri" , "value": "http://example.org/participe" } ,
        "o": { "type": "uri" , "value": "http://example.org/AperoboLyon" }
      }
    ]
  }
}


L'objectif étant de récupérer tous les triplets, comme celui-la : 
      {
        "s": { "type": "uri" , "value": "http://example.org/dog1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } 

c'est à dire qu'on va prendre tout ce qui se trouve après '"bindings": [' et jusqu'à ']'


Pour mieux visualiser, on va modifier la requête et limiter le nombre de résultat à 3, notre variable "requeteTest" sera donc :
http://rdf-smag0.rhcloud.com/ds/query?query=SELECT+*+WHERE+%7B%3Fs+%3Fp+%3Fo+%7D%0D%0ALIMIT+3&output=json

et on va exporter le travail de formatage dans une fonction que l'on va appeler "formateTexte":
--> créer la fonction "formateTexte", la variable "resultat", et modifiez la fonction "When Web1.GotText" comme ceci :



-> Web1.GotText envoie "responseContent" à "formateTexte" dans la variable "texteAFormater"
-> Pour comprendre la fonction "formateTexte", commencez par la droite :
-> On récupère "texteAFormater", on le split/coupe à "bindings": [, on récupère le 2 ème élément de la liste créée par le split, on resplit à ] , on récupère le premier élément, et on envoie ça dans résultat, on affiche résultat dans TextBox1.

Si vous avez bien modifié la requête pour limiter le nombre de résultat à 3, le texte qui devrait maintenant s'afficher dans TextBox1 est celui-ci (revenez sur la page d'accueil et rouvrez l'écran "Visualisation" pour rafraichir, puisque la requete s'execute à l'initialisation de l'écran ou vous pouvez ajouter un bouton qui reprend le code de "When Visualisation.Initialise" pour actualiser plus vite) :  (Avec le formatage en moins )

 {
        "s": { "type": "uri" , "value": "http://example.org/dog1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat1" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" } ,
        "o": { "type": "uri" , "value": "http://example.org/cat" }
      } ,
      {
        "s": { "type": "uri" , "value": "http://example.org/cat" } ,
        "p": { "type": "uri" , "value": "http://www.w3.org/2000/01/rdf-schema#subClassOf" } ,
        "o": { "type": "uri" , "value": "http://example.org/animal" }
      }

Bien bien bien,
D'abord, on "trim" pour enlever les espaces au début et à la fin, et on va continuer à spliter...
L'élement qui séparent nos triplet, maintenant c'est  '} , {'
mais avec un retour à la ligne (ça fait deux heures que je suis dessus !!! mais ça passe ! )
en fait, le séparateur c'est "je ferme l'acolade, je mets un espace, une virgule, le retour à la ligne formalisé par "\n", ensuite, on a six espaces, en une accolade qui ouvre, ça donne : } ,\n {


Pour voir vraiment ce que ça donne, et où on en est, on va remplacer notre TextBox1 et  afficher nos resultats dans un gestionnaire de liste... là, vous pouvez utilisez celui que vous voulez  :
ListPicker, Spinner, ListView... ça dépend de votre besoin, ou de ce que vous souhaitez faire ensuite...
Pour la démo, j'ai mis les trois, et voilà ce que ça nous donne dans le "Designer" et le code modifié depuis la dernière image (avec le bouton actualise ) :


Et la partie code : 



Le resultat est récupérable ici : http://ai2.appinventor.mit.edu/?galleryId=4834449967022080


Evidemment, on va encore splitter pour avoir l'affichage voulu... et surtout choisir entre ListPicker, Spinner et Listview...
Bon en fait, j'hésite entre ListPicker & Listview, on verra plus tard, ... Hop ! out Spinner...

De plus, on va se refaire une petite fonction pour formater les différents élements de la List comme on le souhaite...
Un petit "Layout Horizontal" mettre notre bouton actualise à côté de "Retour Accueil " (optionnel, mais ça laisse plus de place pour le reste.

Commençons par sortir notre liste en l'envoyant à la fonction "formateItem", et on la renvoie tout de suite dans "listeItem" que l'on affiche dans nos "ListPicker" & "Listview" :


Attention, maintenant, on va spiltter... je ne détaille pas, on split sur le motif du début, on prend le deuxième element, on resplit sur le motif de fin, et on prend le premier élement, et ça pour avoir les trois elements de notre triplet : (Sujet, propriete, Objet )


On a maintenant chaque Item de la liste qui ressemble à un truc comme ça :
 "type": "uri" , "value": "http://example.org/dog1"
 "type": "uri" , "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
 "type": "uri" , "value": "http://example.org/animal"

un dernier Split pour récupérer seulement les valeurs  :



Après, on peut encore travailler sur les prefix, mais c'est déjà pas mal pour aujourd'hui...
Pour plus de fun, je repasse la limite des résultats à 100, et je vous mets le bouzin ici :
http://ai2.appinventor.mit.edu/?galleryId=4919353954271232

[ cet article fait partie de la série RDF FACILE - Mon petit BigData ]



07/02/2016

Insert d'informations sur un serveur Fuseki, post

1. installer fuseki pour qu'il soit accessible sur http://127.0.0.1:3030

2. creer un fichier smag.html  dans le repertoire webapp du serveur fuseki, avec le contenu qui suit et y accéder via http://127.0.0.1:3030/smag.html


<!DOCTYPE html>
<!-- https://github.com/scenaristeur/coolitude4/blob/master/Coolitude4/src/org/favedave/smag0/coolitude4/projet/Projet.java -->

<html>
    <body>
  
  
    </body>
   <script>
var debutRequete = "INSERT DATA { GRAPH <http://example/bookStore> {";
var finRequete = "} }";
var data="test";

</script>


<script>
function post(path, params, method) {
    method = method || "post"; // Set method to post by default if not specified.

    // The rest of this code assumes you are not using a library.
    // It can be made less wordy if you use one.
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);
console.log(params);

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
         }
    }


  
  
       document.body.appendChild(form);

    form.submit();
}



<!--post('/contact/', {name: 'Johnny Bravo'}); -->
//post('http://127.0.0.1:3030/test/update', {"update" : update});


function constructRequete(){

 var update  =  "PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ";
 update +=  "PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>";
     update += "PREFIX smag:   <http://smag0.blogspot.fr/NS#>";
     update += "PREFIX zoo:   <http://example.org/zoo#>";
     update += "PREFIX owl: <http://www.w3.org/2002/07/owl#>";
     update += "PREFIX ex: <http://example.org#>";
update+= "INSERT DATA {";
 //update += "GRAPH <http://smag0.blogspot.fr/GraphTest>{";
  //update += "smag:RobokIze    rdf:type         smag:Site .";
  //update +="smag:RobokIze   smag:objectif         'un site de vente revente piece detachees , pour robots, et objets connectes' ." ;
//     update += "ex:cat     rdfs:subClassOf  ex:animal .";
//     update += "zoo:host   rdfs:range       ex:animal .";
//     update += "ex:zoo1    zoo:host         ex:cat2 .";
//     update += "ex:cat3    owl:sameAs       ex:cat2 .";
//    update += "ex:cat3    owl:sameAs       ex:cat2 .";
  
    var sujet=document.getElementById("sujet").value;
    var propriete=document.getElementById("propriete").value;
    var objet=document.getElementById("objet").value;
 update += "smag:"+sujet+"    smag:"+propriete+"         smag:"+objet+" .";

 // fin requete avec graphe var finRequete = "} }";
 var finRequete = "}"; // fin requete sans graphe

update+=finRequete;
console.log(update);


post('http://127.0.0.1:3030/test/update', {"update" : update});
    //console.log(update);
  
    //console.log(document.getElementById("sujet").value);
    //window.location.assign('http://127.0.0.1:3030/smag.html');
//modifier la pause créée par l'alerte --> ceci permet la mise à jour par la fonction post
    alert(update);
    maj();
}

function httpGetAsync(theUrl, callback)
{
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
           callback(xmlHttp.responseText);
            //console.log(xmlHttp.responseText);
             //document.getElementById("result").innerHTML = xhttp.responseText;
    }
    xmlHttp.open("GET", theUrl, true); // true for asynchronous
    xmlHttp.send(null);
}

function updateDiv(data){
var myJSONOBJECT= eval('(' + data+ ')');
// ou var myJSONOBJECT= JSON.parse(data, reviver);
var bindings = myJSONOBJECT.results.bindings;
//console.log("update");
//var resultat="";
var list = document.getElementById('resultats');
while (list.firstChild) {
    list.removeChild(list.firstChild);
}
for(i in bindings) {
  var binding = bindings[i];
  //alert(binding); // a for-loop to print all the bindings
  sujet=binding.s.value.split("#")[1];
  propriete=binding.p.value.split("#")[1];
  objet=binding.o.value.split("#")[1];
//  resultat=sujet +" "+propriete+" "+objet;
 // console.log("resultat :"+resultat);
var entry = document.createElement('li');
entry.appendChild(document.createTextNode(sujet));
entry.appendChild(document.createTextNode("  -> "));
entry.appendChild(document.createTextNode(propriete));
entry.appendChild(document.createTextNode("  -> "));
entry.appendChild(document.createTextNode(objet));
list.appendChild(entry);
}
//document.getElementById("result").innerHTML = resultat;

//var bindings = sr.results.bindings;

// JavaScript  for...in loop iterates
// through the properties of bindings array
// which are [0,1,length-1] as opposed to the
// array item.

//for(i in bindings) {
 // var binding = bindings[i];
 // alert(binding); // a for-loop to print all the bindings
//}

// The only difference here (a subtle one) is
// that the iterator variable is n as opposed to r
// n=name, r=row index
//for(i in bindings) {
  //var binding = bindings[i];
  //for(n in binding) {
  //  alert(binding[n].value); // a nested for-loop to print binding values
 // }
//}



}


function maj(){
//console.log('maj');
httpGetAsync('http://127.0.0.1:3030/test/query?query=select+*+where{%0D%0A%0D%0A%3Fs+%3Fp+%3Fo}%0D%0A&output=json',updateDiv);

}

</script>



<form name="form1" onsubmit="constructRequete()">
<input type="texte" name="q" value="a">

 <input type="submit">
</form>

<ul id="resultats"></ul>

<div id="result">

</div>

<script>

setInterval(function(){ maj(); }, 3000);
//maj();

            var inputSujet = document.createElement("input");
            inputSujet.setAttribute("type", "text");
            inputSujet.setAttribute("name", "sujet");
            inputSujet.setAttribute("id", "sujet");
            inputSujet.setAttribute("placeholder", "Sujet");
          
            form1.appendChild(inputSujet);
          
            var inputPropriete = document.createElement("input");
            inputPropriete.setAttribute("type", "text");
            inputPropriete.setAttribute("name", "propriete");
            inputPropriete.setAttribute("id", "propriete");
            inputPropriete.setAttribute("placeholder", "propriete");

            form1.appendChild(inputPropriete);
          
            var inputObjet = document.createElement("input");
            inputObjet.setAttribute("type", "text");
            inputObjet.setAttribute("name", "objet");
            inputObjet.setAttribute("id", "objet");
            inputObjet.setAttribute("placeholder", "Objet");

            form1.appendChild(inputObjet);
  
    // console.log(document.getElementById("sujet").value);
</script>


</html>