Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    86

    Richiamare una funzione a runtime

    Come da titolo sto cercando di richiamrare un funzione durante l'esecuzione del codice il cui scopo è leggere un foglio xml. Al momento in cui interviene un tag(xml) chiamato "action" il codice dovrebbe leggere il contenuto del tag "innerHTML" che poi sarebbe il nome della funzione da lanciare e lanciarla. E' possibile fare ciò? Non ho trovato molto materiale online, aiuto please.

  2. #2
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    Per la lettura dell'XML ti può essere utile questa funzione:

    codice:
    function buildValue(sValue) {
    	if (/^\s*$/.test(sValue)) { return(null); }
    	if (/^(true|false)$/i.test(sValue)) { return(sValue.toLowerCase() === "true"); }
    	if (isFinite(sValue)) { return(parseFloat(sValue)); }
    	if (isFinite(Date.parse(sValue))) { return(new Date(sValue)); }
    	return(sValue);
    }
    
    function getXMLData (oXMLParent) {
    	var /* TRUE is the default value for empty nodes */ vResult = true; nLength = 0, sTxtContent = "";
    	if (oXMLParent.hasAttributes()) {
    		vResult = {};
    		for (nLength; nLength < oXMLParent.attributes.length; nLength++) {
    			iAttrib = oXMLParent.attributes.item(nLength);
    			vResult["@" + iAttrib.nodeName.toLowerCase()] = buildValue(iAttrib.nodeValue.replace(/^\s+|\s+$/g, ""));
    		}
    	}
    	if (oXMLParent.hasChildNodes()) {
    		var iKey, iValue, iXMLChild;
    		for (var iChildId = 0; iChildId < oXMLParent.childNodes.length; iChildId++) {
    			iXMLChild = oXMLParent.childNodes.item(iChildId);
    			if (iXMLChild.nodeType === 1 && !iXMLChild.prefix) {
    				if (nLength === 0) { vResult = {}; }
    				iKey = iXMLChild.nodeName.toLowerCase();
    				iValue = getXMLData(iXMLChild);
    				if (vResult.hasOwnProperty(iKey)) {
    					if (vResult[iKey].constructor !== Array) { vResult[iKey] = [vResult[iKey]]; }
    					vResult[iKey].push(iValue);
    				} else { vResult[iKey] = iValue; nLength++; }
    			} else if (iXMLChild.nodeType === 3) { sTxtContent += iXMLChild.nodeValue.replace(/^\s+|\s+$/g, ""); }
    			else if (iXMLChild.nodeType === 4) { sTxtContent += iXMLChild.nodeValue; }
    		}
    	}
    	if (nLength > 0) { vResult.keyValue = buildValue(sTxtContent); Object.freeze(vResult); }
    	else if (sTxtContent) { vResult = buildValue(sTxtContent); }
    
    	return(vResult);
    }
    
    var oAlbero = getXMLData(oResponseXML);
    // abbiamo ottenuto il nostro albero di oggetti javascript! provare per credere: alert(JSON.stringify(oAlbero));
    Creare la funzione dal contenuto dell'XML:

    codice:
    var miaFunzione = new Function(oAlbero.nodofiglio1.nodofiglio2.etc.etc.action);
    miaFunzione();
    Oppure, se devi estrarre solo il contenuto di un nodo, è inutile leggere tutto l'XML (quindi dimentica la funzione che ti ho postato!!):

    codice:
    var miaFunzione = new Function(tuoNodo.nodeValue);
    miaFunzione();

  3. #3
    se cerchi materiale online in proposito forse puoi vedere questa pagina: mozilla xml

  4. #4
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    86
    Grazie carlomarx, var oAlbero = getXMLData(oResponseXML);, questo è il comando che mi interessava ;-) lo provo subito e ti faccio sapere. Anche se io ho il nome della funzione dentro il nodo e non la funzione vera e propria dovrebbe funzionare lo stesso vero? Ti faccio sapere.

  5. #5
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    Originariamente inviato da m4rc087
    Grazie carlomarx, var oAlbero = getXMLData(oResponseXML);, questo è il comando che mi interessava ;-) lo provo subito e ti faccio sapere
    Figurati :-)
    Bada che quando ho scritto quella funzione ho differenziato i nodi non contenenti attributi, del tipo:

    codice:
    <nodo>contenuto del nodo</nodo>
    dai nodi contenenti attributi, del tipo:

    codice:
    <nodo attributo="valore">contenuto del nodo</nodo>
    nel primo caso il testo contenuto nel nodo sarà accessibile così:

    codice:
    oAlbero.nodo
    mentre nel secondo caso così:

    codice:
    oAlbero.nodo.keyValue
    mentre l'attributo sarà accessibile così:
    codice:
    oAlbero.nodo.@attributo
    Se vai alla pagina che ti ha suggerito TrueLies troverai altre due funzioni simili che avevo postato precedentemente. È anche spiegata la differenza. Ritengo comunque che questa sia la più sensata&hellip;

  6. #6
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    Alt!! Ho beccato un punto e virgola di troppo che ti genera variabili globali!! Usa questa versione corretta:

    codice:
    function buildValue(sValue) {
    	if (/^\s*$/.test(sValue)) { return(null); }
    	if (/^(true|false)$/i.test(sValue)) { return(sValue.toLowerCase() === "true"); }
    	if (isFinite(sValue)) { return(parseFloat(sValue)); }
    	if (isFinite(Date.parse(sValue))) { return(new Date(sValue)); }
    	return(sValue);
    }
    
    function getXMLData (oXMLParent) {
    	var vResult = /* true is the default value for empty nodes */ true, nLength = 0, sTxtContent = "";
    	if (oXMLParent.hasAttributes()) {
    		vResult = {};
    		for (nLength; nLength < oXMLParent.attributes.length; nLength++) {
    			iAttrib = oXMLParent.attributes.item(nLength);
    			vResult["@" + iAttrib.nodeName.toLowerCase()] = buildValue(iAttrib.nodeValue.replace(/^\s+|\s+$/g, ""));
    		}
    	}
    	if (oXMLParent.hasChildNodes()) {
    		var iKey, iValue, iXMLChild;
    		for (var iChildId = 0; iChildId < oXMLParent.childNodes.length; iChildId++) {
    			iXMLChild = oXMLParent.childNodes.item(iChildId);
    			if (iXMLChild.nodeType === 1 && !iXMLChild.prefix) {
    				if (nLength === 0) { vResult = {}; }
    				iKey = iXMLChild.nodeName.toLowerCase();
    				iValue = getXMLData(iXMLChild);
    				if (vResult.hasOwnProperty(iKey)) {
    					if (vResult[iKey].constructor !== Array) { vResult[iKey] = [vResult[iKey]]; }
    					vResult[iKey].push(iValue);
    				} else { vResult[iKey] = iValue; nLength++; }
    			} else if (iXMLChild.nodeType === 3) { sTxtContent += iXMLChild.nodeValue.replace(/^\s+|\s+$/g, ""); }
    			else if (iXMLChild.nodeType === 4) { sTxtContent += iXMLChild.nodeValue; }
    		}
    	}
    	if (nLength > 0) { vResult.keyValue = buildValue(sTxtContent); Object.freeze(vResult); }
    	else if (sTxtContent) { vResult = buildValue(sTxtContent); }
    
    	return(vResult);
    }

  7. #7
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    Cmq se non è troppo lungo prova a postare il foglio XML, indicando il punto in cui si trova la funzione&hellip;

  8. #8
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    86
    xml body


    <action>nome funzione();</action>

    la funzione ovviamente è scritta è caricata in un foglio js apparte.

  9. #9
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    Prova a postare TUTTO il foglio XML (o almeno tutti i nodi genitori a partire dal root). Comunque la soluzione che ti avevo proposto io con new Function va bene (ed è preferibile a eval perché più performante) se la funzione da invocare è globale. Se non è globale devi usare per forza eval(oAlbero.nodofiglio1.nodofiglio2.etc.etc.actio n): il costruttore di funzioni non è in grado di accedere al local scope. Se la funzione da invocare è globale puoi anche sintetizzare la scrittura col costruttore di funzioni così:

    codice:
    // altro codice
    (new Function(oAlbero.nodofiglio1.nodofiglio2.etc.etc.action))();
    // altro codice
    Se il tag action si trova immediatamente dentro il document e non ha nodi genitori, una volta generato l'oggetto oAlbero, devi fare così:

    codice:
    // altro codice
    (new Function(oAlbero.action))();
    // altro codice
    Sorry, adesso devo proprio scappare...

  10. #10
    Oh scusa un attimo... stai leggendo un file xml... siccome lo puoi leggere anche dal lato del server (che so php o quel che è) e siccome non è chiarissimo come avviene questa lettura nè se avviene nella maniera più semplice (ok, tu lo leggi, si direbbe, passandolo a un javascript): ma siamo sicuri non verrebbe meglio passandolo al server? perchè mi pare di capire che tu stai collezionando dati che poi vorrai stampare o inviare altrove... e quelli te li legge anche un server anzichè appesantire la macchina di un client (con tutte le problematiche di performance che comporta, e di compatibilità con tutto un inferno di browser versioni e sottoversioni... - e dipende anche da quanto questo xml è ampio)

    Ora, se lo legge il server, php ha una gran quantità di funzioni che si occupano di xml ma c'è un ma... sono tutte poco performanti - infatti, all' atto pratico, leggere un file xml sul lato server è più conveniente farlo trattandolo come un file di testo a botte di espressioni regolari: è più veloce che usare le funzioni php dedicate all' xml.

    Vedi un po' te se la ipotesi fa al caso tuo: non saresti il primo che si imbarca in una procedura complicatissima solo per accorgersi mesi dopo che un approccio diverso era più veloce, otteneva lo scopo, e produceva codici più portabili.

    ps cioè ti sto dicendo questo: non è detto che un file xml debba essere trattato per forza come xml: javascript potrebbe in certi casi trattarlo con successo anche con il semplice DOM (e sono nodi...), e PHP come un mero file di testo. Sono alternative che sta a te valutare - idealmente, prima di tuffarsi.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.