XML - esiste un modo per leggere una riga alla volta
(1/1)
Maverich:
mi trovo a voler leggere un XML riga per riga (come un normale file testo), e sotituire le stringhe usate come identificatore (es: testo ***CognomeNome*** testo).
ho preso come riferimento un testo Libre/OpenOffice (file content.xml)
il problema e' che seguendo questa logica
--- Codice: --- b := true; repeat begin ReadLn(F, sTesto); //legge riga F: TextFile repeat //ricerca identificatore i := Pos('***CognomeNome***', sTesto); if i > 0 then begin Memo1.Lines.Add(sTesto); sModificato := Replace(sTesto, '***CognomeNome***', 'Pippo'); b := False; end else b := True; until b; end; until eof(F);
....
function TForm1.Replace(Dest, SubStr, Str: string): string; var iPosition: Integer; begin iPosition:=Pos(SubStr, Dest); Delete(Dest, iPosition, Length(SubStr)); Insert(Str, Dest, iPosition); Result:=Dest; end;
--- Termina codice ---
ottengo una stringa lunga 1^ riga .... trova il carattere equivalente alla nuova riga <?xml version="1.0" encoding="UTF-8"?> 2^ riga tutto il resto del documento (trova il carattere equivalente alla nuova riga solo alla fine del documento)
cosi' facendo trovo solo il primo identificatore, e per trovare i successivi devo sovrascrivere il file XML Chiudere e Riaprire.
ho provato anche la unit XMLRead, ma TextContents equivale al ReadLn su un TextFile
--- Codice: --- procedure TForm1.Button4Click(Sender: TObject); var F: TextFile; sTesto, sModificato: string; i, j : integer; Documento: TXMLDocument; Child: TDOMNode; b: boolean; begin ReadXMLFile(Documento, 'E:\Lazarus\TestZip2\content.xml'); Memo1.Lines.Clear; // using FirstChild and NextSibling properties Child := Documento.DocumentElement.FirstChild; while Assigned(Child) do begin Memo1.Lines.Add(Child.TextContent); //Memo1.Lines.Add(Child.NodeValue); //Memo1.Lines.Add(Child.Attributes.Item[0].NodeValue); //Child.Attributes.Item[0].NodeValue // using ChildNodes method with Child.ChildNodes do try for j := 0 to (Count - 1) do begin //Memo1.Lines.Add(Item[j].NodeName); // + ' ' + Item[j].FirstChild.NodeValue); Memo2.LInes.Clear; Memo2.Lines.Add(Item[j].TextContent); end; finally Free; end; Child := Child.NextSibling; end; Documento.Free; end;
--- Termina codice ---
nomorelogic:
probabilmente il carattere di CR+FL lo trovi solamente alla fine della prima riga ed alla fine del file.
prova ad aprire il file originale con un normale editor di testo e togli "a capo automatico" dall impostazioni, molto probabilmente vedrai 2 sole righe. in alternativa, se le righe sono più di 2, aprilo in modalità esadecimale, magari gli "a capo" sono dei semplici LF mentre ReadLn cerca CR+FL (almeno mi pare di ricordare :)).
comunque non credo sia un problema il numero delle righe :) in alternativa a Pos, per fare tutto il lavoro in un colpo solo, potresti usare :
--- Codice: --- sModificato:=sTesto; i := Pos('***CognomeNome***', sModificato); while i > 0 do begin sModificato := Replace(sModificato, '***CognomeNome***', 'Pippo'); i := Pos('***CognomeNome***', sModificato); end; Memo1.Lines.Add(sModificato);
--- Termina codice ---
Stilgar:
Se fornisci un content.xml di riferimento diventa più semplice aiutarti a tarare un algoritmo ;) cmq. Se chiedi il risultato documentElement.textContent, viene utilizzato tutto l'albero per comporre la stringa. Quello che dovresti fare è identificare il nodo che contiene quello che ti interessa. Con XPATH diventa qualche cosa del tipo "text()==xxx" per ottenere i nodi. L'implementazione che viene fornita con Lazarus/FPC, non è un fulmine di guerra, ma lavora bene. Se devi puntare a 100 elementi, va un pochino in crisi ;) Una possibile richiesta XPATH dovrebbe essere del tipo --- Codice: --- //text()=="***CognomeNome***" --- Termina codice --- (Fatta al volo, non verificata ;) ) Per tarare le espressioni regolari per xpath utilizzo un plug per FF. (http://code.google.com/p/xpathchecker/) EDIT: PS1: Tutti i padri con textContent includono il testo dei figli. PS2: http://www.freepascal.org/docs-html/rtl/sysutils/stringreplace.html Cambia funzione per la sostituzione di tutte le occorenze ;)
Stilgar:
Allora, ho usato Word 2010.
da TXMLDocument, chiedi i nodi (getElementsByTagName) "text:p" In questo modo hai tutti i "paragrafi". Modifichi il textContent di questi nodi.