Visualizzazione dei risultati da 1 a 5 su 5

Discussione: Scrittura su file xml

  1. #1

    Scrittura su file xml

    Ciao a tutti,
    Stavo provando a far scrivere a PHP un file XML.

    Il file XML contiene delle news e da un pannello di amministrazione volevo permettere l'inserimento di nuove news (ed eventuale cancellazione, ma questo lo vedremo in un'altra occasione se sarà necessario).

    Così, da inesperta di file XML ho pensato che potevo leggere il file in una stringa, e poi con substr_replace sostituire alla parte di questa stringa che contiene il tag del nodo principale una stringa composta opportunamente con i dati passati dal form per l'inserimento della news.

    Forse sono stata un pò ingenua perchè sicuramente ci saranno metodi più opportuni quantomeno, basati sugli array, in ogni caso quello che ho fatto non funziona, apparentemente non succede nulla al file XML in questione che resta integro.

    il codice usato è:

    Codice PHP:
    <?
    $nomefile 
    "../public/xmlnews.xml";
    if(isset(
    $_POST['submit'])){
    $datains $_POST['giorno'];
    $newsins $_POST['corponews'];
    $stringains "<elenco><news dato = \"$newsins\" datas =\"$datains\"></news>";
    // lettura e scrittura su file
    $contenutofile file_get_contents ($nomefile);
    $inserimento substr_replace($contenutofile$stringains17);
    $fp fopen ($nomefile"w");
    $fw fwrite ($fp$inserimento);
    fclose($fp);
    }
    ?>
    Grazie a tutti in anticipo
    Viviamo tutti in una palude di fango, ma alcuni di noi guardano le Stelle http://www.comunicareoltre.it

  2. #2
    Nessun suggerimento sulla scrittura di file xml? in questi giorni ho dato un'occhiata in giro e mi sono accorta che tra DOM e SAX e altro ce n'è di materiale da studiare... Mi pare di aver capito che SAX funziona con PHP 5 e DOM è un'API che deve essere installata sul server, quindi se uso PHP 4 e il server non è il mio non posso usare nessuna delle due, sbaglio?

    Il mio metodo, a parte che non funziona, è davvero così sciocco e devo intraprendere altre strade? se si quali? In fondo non è una semplice scrittura su file? se io so che quello che devo scrivere lo devo mettere in testa al file...

    In ogni caso per la visualizzazione del contenuto del file xml ho trovato un fantastico script che molto agevolmente mi permette di visualizzare quello che ho sull'XML tramite una serie di funzioni che convertono in array il contenuto dell'XML... Ma se ce l'ho già come array grazie a queste funzioni, non posso manipolarlo come tale?

    Per chiunque volesse aiutarmi allego il codice che sto usando, che (ripeto) non è mio. al termine del quale ho l'array $data all'interno del quale trovo gli attributi che mi interessano come

    $data[$i][child][$r][dato] che è il corpo della news
    $data[$i][child][$r][datas] che è la data della news

    il codice è su 2 file:

    parserXML.php

    Codice PHP:
    <? 
    $struct 
    = array(); 
     
    # Funzioni di callback 
    function startElement($parser$name$attrs

      global 
    $struct
     
      
    $tag = array("name"=>$name,"attrs"=>$attrs); 
     
      
    array_push($struct,$tag); 

     
    function 
    data($parser$data

      global 
    $struct,$i
     
      if(
    trim($data)) { 
        
    $struct[count($struct)-1]['data']=$data
      } 

     
    function 
    endElement($parser$name

      global 
    $struct
     
      
    $struct[count($struct)-2]['child'][] = $struct[count($struct)-1]; 
     
      
    array_pop($struct); 

     
    # Funzione che parsa il file passatogli nell'argomento e restituisce 
    # una struttura ad albero oggetti-array contenente il documento 
    function parse_file($file

      global 
    $struct
     
      
    $xml_parser xml_parser_create(); 
      
    xml_set_element_handler($xml_parser"startElement""endElement"); 
      
    xml_set_character_data_handler($xml_parser"data"); 
      
    $parse xml_parse($xml_parser,file_get_contents($file)); 
     
      if(!
    $parse) { 
        die(
    "XML parsing error"); 
        
    xml_parser_free($xml_parser); 
      } 
     
      return 
    $struct

    ?>
    news_sys.php

    Codice PHP:
    <? 
    include ("parserXML.php"); 
     
    $fdata "../public/xmlnews.xml"# database 
    $data parse_file($fdata); # parsa il file-database 
     
    if(!isset($_GET['news'])){ 
      
    $news_for_page="all"# n. predefinito di news per pagina 
    }else{ 
      
    # si puo' decidere di passare allo script 
      
    $news_for_page $_GET['news']; # tramite GET la variabile news col n. di 
      # news per pagina da visualizzare 

     
    # il numero totale delle news 
    $news_num count($data[0]['child']); # presenti nel database 
     
    # Se il n. tot. di news e' minore del numero di news da visualizzare 
    # Oppure se bisogna visualizzare tutte le news 
    if ($news_num <= $news_for_page or $news_for_page=="all"){ 
      
    $offset 0
      
    # Memorizza tutte le news 
      
    for ($i $news_num 1$i >= 0$i--){ 
        
    $date_news[$offset] = $data[0]['child'][$i]['attrs']['DATAS']; 
        
    $title_news[$offset] = $data[0]['child'][$i]['attrs']['DATO']; 
        
    $data_news[$offset] = $data[0]['child'][$i]['data']; 
        
    $offset++; 
      } 

     
    # Se il n. tot. di news e' maggiore di quelle da visualizzare 
    if ($news_num $news_for_page){ 
      
    $offset 0
      
    # Memorizza solo le ultime '$news_for_page' news 
      
    for ($i $news_num 1$i >= $news_num $news_for_page$i--){ 
        
    $date_news[$offset] = $data[0]['child'][$i]['attrs']['DATAS']; 
        
    $title_news[$offset] = $data[0]['child'][$i]['attrs']['DATO']; 
        
    $data_news[$offset] = $data[0]['child'][$i]['data']; 
        
    $offset++; 
      } 

    ?>
    Per la visualizzazione

    Codice PHP:
    <table width="350"><? 
     
     
    # Se il n. tot. di news e' minore del numero di news da visualizzare 
    # Oppure se bisogna visualizzare tutte le news 
    if ($news_num <= $news_for_page or $news_for_page=="all"){ 
      
    $offset=0
      
    # Visualizza tutte le news 
      
    for ($i $news_num 1$i >= 0$i--){ 
    ?> 
        <tr>
        <td align="left">[b]<?=$date_news[$offset]?>[/b]</td>
        </tr> 
        <tr>
        <td align="left"><?=$title_news[$offset]?>
    </td>
        </tr>
        <tr>
        <td></td>
        </tr>
    <? 
        $offset
    ++; 
      } 

     
    # Se il n. tot. di news e' maggiore di quelle da visualizzare 
    if ($news_num $news_for_page){ 
      
    $offset 0
      
    # Visualizza solo le ultime '$news_for_page' news 
      
    for ($i $news_num $news_for_page$i <= $news_num 1$i++){ 
    ?> 
       <tr>
        <td align="left">[b]<?=$date_news[$offset]?>[/b]</td>
        </tr> 
        <tr>
        <td align="left"><?=$title_news[$offset]?>
    </td>
        </tr>
    <? 
        $offset
    ++; 
      } 

    ?>

    </table>
    Scusate il post così lungo

    Grazie in anticipo

    PS mi pare che lo script che cito sia all'interno di un tutorial di Michele Buonaiuto, non ricordo l'indirizzo, ma mi sembra giusto citarlo
    Viviamo tutti in una palude di fango, ma alcuni di noi guardano le Stelle http://www.comunicareoltre.it

  3. #3
    Sono riuscita a scrivere il file xml con l'inserimento da un form (seguendo il metodo che ho illustrato nel primo post)... Ora ho un problema con la cancellazione di un nodo dal file xml.

    Dagli script che ho postato prima ricavo 2 array che uso per visualizzare il contenuto del file.

    Questi 2 array sono:

    $date_news (che contiene le date)
    $title_news (che contiene il contenuto della news)

    accanto a ciascuna news quando le visualizzo vorrei far apparire un link cliccando sul quale la news corrispondente venga cancellata. Dovrei quindi passare una variabile con GET alla pagina stessa che visualizza le news e poi con unset cancellare l'elemento corrispondente da ciascuno dei 2 array e poi riconvertire gli array scrivendo lo stesso file XML che sto usando che verrà successivamente visualizzato dallo stesso script che ho postato prima.

    Siccome la visualizzazione del contenuto dei 2 array si basa su un ciclo for con indice $i avevo pensato che il link corrispondente a ciascuna news potesse essere del tipo

    pagina.php?action=cancella$i

    Poi passo la variabile $action con GET

    $action = $_GET['action'];

    poi scorro uno dei 2 array in un ciclo for per cancellare l'elemento corrispondente dell'array:
    Codice PHP:
    for ($r=0;$r<count($date_news);$r++){
    if (
    $action == $r) {
    unset(
    $date_news[$r]);
    unset(
    $date_title[$r]);
    //trasforma gli array in un file xml
    //scrivi il file xml
    }

    In teoria dovrebbe funzionare, solo che non so come creare lo script inverso di quello che ho postato prima, che come ho detto non è farina del mio sacco.

    Ho trovato una classe su PHPCLASSES.org che si chiama array2xml ma non funziona o non so farla funzionare...

    Qualcuno può aiutarmi?
    Viviamo tutti in una palude di fango, ma alcuni di noi guardano le Stelle http://www.comunicareoltre.it

  4. #4
    Diciamo che c'è un microscopico passo avanti:

    l'array $data che rappresenta il file XML è così strutturato:

    Array
    (
    [0] => Array
    (
    [name] => ELENCO
    [attrs] => Array
    (
    )

    [child] => Array
    (
    [0] => Array
    (
    [name] => NEWS
    [attrs] => Array
    (
    [DATO] => corpo news 1
    [DATAS] => 28-02-2006
    )

    )

    [1] => Array
    (
    [name] => NEWS
    [attrs] => Array
    (
    [DATO] => corpo news 2
    [DATAS] => 21-03-2006
    )

    )

    )

    )

    )

    Il file XML è del tipo

    <elenco>
    <news dato = "corpo della news" datas = "01-01-2006">
    </news>
    <news dato = "corpo dell'altra news e così via" datas = "02-01-2006">
    </news>
    </elenco>

    Se voglio cancellare dall'elenco la prima news dovrò cancellare l'elemento dell'array $data di posizione $data[0][child][0], se voglio cancellare la seconda news dovrò cancellare l'elemento dell'array $data di posizione $data[0][child][1] e così via.

    Così nel ciclo for di visualizzazione dell'array creo un link accanto a ciascuna news del tipo <a href="pagina.php?action=$i">

    Passo alla stessa pagina la variabile $action con GET

    $action = $_GET['action'];

    scorro nuovamente l'array con un ciclo for e con una condizione if cancello l'elemento dell'array $data[0][child] di posto $i

    for ($r=0;$r<count($data[0][child]);$r++){
    if ($action == $r) {
    unset($data[0][child][$r]);
    }
    }

    Poi devo riscrivere il file xml altrimenti il lavoro sarà stato inutile. Potrei crearmi una stringa contenente l'intero file e sostituire al posto dei contenuti delle news e delle date le corrispondenti posizioni dell'array $data. Una cosa del genere:

    $stringa = "<elenco><news dato =\'$data[0][child][0][attrs][dato]\' datas =\'$data[0][child][0][attrs][datas]\'></news></elenco>";

    Solo che questo va bene se ho una sola news, non saprei proprio impostare un ciclo for che mi crei una stringa con tanti campi <news> quante sono le news...

    Sto straparlando vero? per questo non mi aiuta nessuno?
    Viviamo tutti in una palude di fango, ma alcuni di noi guardano le Stelle http://www.comunicareoltre.it

  5. #5
    Ho trovato queste funzioni, qualcuno mi aiuta ad adattarle al mio file xml? se funzionassero avrei risolto... (ma non mi sente nessuno?)

    Codice PHP:
    <?php 
    // {{{ toString() 
    /** 
     * This method converts a file to a string. It returns an Error object if it is unable to open the file. 
     * 
     * @param    fileName String. The name of the file to convert. 
     * 
     * @return    String 
     * @author  simgar 
     */ 

    function & toString$fileName 

        if (
    $content_array file($fileName)) 
        { 
            return 
    implode(""$content_array); 
        } 
        else 
        { 
            
    // Error 
            
    return false
        } 

    // }}} 

    // {{{ xmlFileToArray() 
    /** 
     * This static method converts an xml file to an associative array  
     * duplicating the xml file structure. 
     * 
     * @param    $fileName. String. The name of the xml file to convert.  
     *             This method returns an Error object if this file does not  
     *             exist or is invalid. 
     * @param    $includeTopTag. booleal. Whether or not the topmost xml tag  
     *             should be included in the array. The default value for this is false. 
     * @param    $lowerCaseTags. boolean. Whether or not tags should be  
     *            set to lower case. Default value for this parameter is true. 
     * @access    public static 
     * @return    Associative Array 
     * @author    Jason Read <jason@ace.us.com> 
     */ 
    function & xmlFileToArray($fileName$includeTopTag false$lowerCaseTags true

        
    // Definition file not found 
        
    if (!file_exists($fileName)) 
        { 
            
    // Error 
            
    return false
        } 
        
    $p xml_parser_create(); 
        
    xml_parse_into_struct($p,toString($fileName),$vals,$index); 
        
    xml_parser_free($p); 
        
    $xml = array(); 
        
    $levels = array(); 
        
    $multipleData = array(); 
        
    $prevTag ""
        
    $currTag ""
        
    $topTag false
        foreach (
    $vals as $val
        { 
            
    // Open tag 
            
    if ($val["type"] == "open"
            { 
                if (!
    _xmlFileToArrayOpen($topTag$includeTopTag$val$lowerCaseTags,  
                                               
    $levels$prevTag$multipleData$xml)) 
                { 
                    continue; 
                } 
            } 
            
    // Close tag 
            
    else if ($val["type"] == "close"
            { 
                if (!
    _xmlFileToArrayClose($topTag$includeTopTag$val$lowerCaseTags,  
                                                
    $levels$prevTag$multipleData$xml)) 
                { 
                    continue; 
                } 
            } 
            
    // Data tag 
            
    else if ($val["type"] == "complete" && isset($val["value"])) 
            { 
                
    $loc =& $xml
                foreach (
    $levels as $level
                { 
                    
    $temp =& $loc[str_replace(":arr#"""$level)]; 
                    
    $loc =& $temp
                } 
                
    $tag $val["tag"]; 
                if (
    $lowerCaseTags
                { 
                    
    $tag strtolower($val["tag"]); 
                } 
                
    $loc[$tag] = str_replace("\\n""\n"$val["value"]); 
            } 
            
    // Tag without data 
            
    else if ($val["type"] == "complete"
            { 
                
    _xmlFileToArrayOpen($topTag$includeTopTag$val$lowerCaseTags,  
                                          
    $levels$prevTag$multipleData$xml); 
                
    _xmlFileToArrayClose($topTag$includeTopTag$val$lowerCaseTags,  
                                          
    $levels$prevTag$multipleData$xml); 
            } 
        } 
        return 
    $xml

    // }}} 

    // {{{ _xmlFileToArrayOpen() 
    /** 
     * Private support function for xmlFileToArray. Handles an xml OPEN tag. 
     * 
     * @param    $topTag. String. xmlFileToArray topTag variable 
     * @param    $includeTopTag. boolean. xmlFileToArray includeTopTag variable 
     * @param    $val. String[]. xmlFileToArray val variable 
     * @param    $currTag. String. xmlFileToArray currTag variable 
     * @param    $lowerCaseTags. boolean. xmlFileToArray lowerCaseTags variable 
     * @param    $levels. String[]. xmlFileToArray levels variable 
     * @param    $prevTag. String. xmlFileToArray prevTag variable 
     * @param    $multipleData. boolean. xmlFileToArray multipleData variable 
     * @param    $xml. String[]. xmlFileToArray xml variable 
     * @access    private static 
     * @return    boolean 
     * @author    Jason Read <jason@ace.us.com> 
     */ 
    function _xmlFileToArrayOpen(& $topTag, & $includeTopTag, & $val, & $lowerCaseTags,  
                                 & 
    $levels, & $prevTag, & $multipleData, & $xml

        
    // don't include top tag 
        
    if (!$topTag && !$includeTopTag
        { 
            
    $topTag $val["tag"]; 
            return 
    false
        } 
        
    $currTag $val["tag"]; 
        if (
    $lowerCaseTags
        { 
            
    $currTag strtolower($val["tag"]); 
        } 
        
    $levels[] = $currTag
         
        
    // Multiple items w/ same name. Convert to array. 
        
    if ($prevTag === $currTag
        { 
            if (!
    array_key_exists($currTag$multipleData) ||  
                !
    $multipleData[$currTag]["multiple"]) 
            { 
                
    $loc =& $xml
                foreach (
    $levels as $level
                { 
                    
    $temp =& $loc[$level]; 
                    
    $loc =& $temp
                } 
                
    $loc = array($loc); 
                
    $multipleData[$currTag]["multiple"] = true
                
    $multipleData[$currTag]["multiple_count"] = 0
            } 
            
    $multipleData[$currTag]["popped"] = false
            
    $levels[] = ":arr#" . ++$multipleData[$currTag]["multiple_count"]; 
        } 
        else 
        { 
            
    $multipleData[$currTag]["multiple"] = false
        } 
         
        
    // Add attributes array 
        
    if (array_key_exists("attributes"$val)) 
        { 
            
    $loc =& $xml
            foreach (
    $levels as $level
            { 
                
    $temp =& $loc[str_replace(":arr#"""$level)]; 
                
    $loc =& $temp
            } 
            
    $keys array_keys($val["attributes"]); 
            foreach (
    $keys as $key
            { 
                
    $tag $key
                if (
    $lowerCaseTags
                { 
                    
    $tag strtolower($tag); 
                } 
                
    $loc["attributes"][$tag] = & $val["attributes"][$key]; 
            } 
        } 
        return 
    true

    // }}} 

    // {{{ _xmlFileToArrayClose() 
    /** 
     * Private support function for xmlFileToArray. Handles an xml OPEN tag. 
     * 
     * @param    $topTag. String. xmlFileToArray topTag variable 
     * @param    $includeTopTag. boolean. xmlFileToArray includeTopTag variable 
     * @param    $val. String[]. xmlFileToArray val variable 
     * @param    $currTag. String. xmlFileToArray currTag variable 
     * @param    $lowerCaseTags. boolean. xmlFileToArray lowerCaseTags variable 
     * @param    $levels. String[]. xmlFileToArray levels variable 
     * @param    $prevTag. String. xmlFileToArray prevTag variable 
     * @param    $multipleData. boolean. xmlFileToArray multipleData variable 
     * @param    $xml. String[]. xmlFileToArray xml variable 
     * @access    private static 
     * @return    boolean 
     * @author    Jason Read <jason@ace.us.com> 
     */ 
    function _xmlFileToArrayClose(& $topTag, & $includeTopTag, & $val, & $lowerCaseTags,  
                                  & 
    $levels, & $prevTag, & $multipleData, & $xml

        
    // don't include top tag 
        
    if ($topTag && !$includeTopTag && $val["tag"] == $topTag
        { 
            return 
    false
        } 
        if (
    $multipleData[$currTag]["multiple"]) 
        { 
            
    $tkeys array_reverse(array_keys($multipleData)); 
            foreach (
    $tkeys as $tkey
            { 
                if (
    $multipleData[$tkey]["multiple"] && !$multipleData[$tkey]["popped"]) 
                { 
                    
    array_pop($levels); 
                    
    $multipleData[$tkey]["popped"] = true
                    break; 
                } 
                else if (!
    $multipleData[$tkey]["multiple"]) 
                { 
                    break; 
                } 
            } 
        } 
        
    $prevTag array_pop($levels); 
        if (
    strpos($prevTag"arr#")) 
        { 
            
    $prevTag array_pop($levels); 
        } 
        return 
    true

    // }}} 
    ?>
    Viviamo tutti in una palude di fango, ma alcuni di noi guardano le Stelle http://www.comunicareoltre.it

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.