![]() |
Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen
Liste der Anhänge anzeigen (Anzahl: 3)
Bislang musste ich mich nicht näher mit XML-Dateien befassen, so dass ich mich in Bezug darauf als relativen Anfänger bezeichnen kann.
Ich habe XML-Dateien (Teile von Word bzw. Libre-Office-Dokument-Vorlagen), dort sind Platzhalter drin und die möchte ich entweder durch einen einzeiligen Text oder durch mehrzeiligen Text (am besten mit Softbreak-Umbrüchen) ersetzen. Zwar kriege ich das vom Prinzip her durch auch mit einfachem Suchen und ersetzen hin, aber wenn ein Anwender die Vorlagen-Dokumente verändert, dann ändert sich die XML-Stuktur (die Tags) in einer Art und Weise, die ich nicht vorhersehen kann und dann funktionieren meine Suchen- und Ersetzen Bemühungen nicht mehr (die TAG-Struktur kommt dann irgendwie durcheinander). Also Anlass sich jetzt doch mal mit XML befassen zu müssen. Mir liegen die XML-Dateien als TMemorystream vor, in einer FMX-Anwendung. Kann mir freundlicherweise jemand sagen, welche mit Delphi mitgelieferte XML-Klasse ich hier verwenden sollte? Habe hier TXMLDocument gefunden, da kann ich das XML-dokument per Stream oder file laden. Finde aber keine Items-Eigenschaft oder ähnliches, wie ich da durch iterieren kann. Also, wie iteriere ich hier durch die einzelnen Knoten, um meine Platzhalter-Texte zu finden und wie ersetze ich ihn (einzeilig dürfte einfach sein, aber mehrzeilig)? In der Anlage mal die Beispiel-XML-Dateien und wie diese als Vorlage (hier in Word) aussehen. Den Platzhalter {Adr_Alles} möchte ich durch eine korrekt formatierte Adresse ersetzen, also mehrere Zeilen (Anrede, Name, Straße, PLZ und Ort), die anderen Platzhalter durch einfachen, einzeiligen Text. |
AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen
TXMLDocument ist schon genau richtig.
Das hat die Eigenschaft DocumentElement, das ist der Stammknoten vom Typ IXMLNode. Dieser hat wie jeder andere Knoten die Eigenschaft ChildNodes. Darüber kannst du iterieren bzw. rekursiv in die tieferen Ebenen einsteigen. Dann musst du nur in der Eigenschaft Text des jeweiligen Knotens nach dem Platzhalter suchen und deinen Text da rein schreiben. Wegen der Zeilenumbrüche: Speichere doch einfach mal ein Word-Dokument mit der Adresse, so wie du sie haben willst, und schau nach, was Word da in die XML geschrieben hat. |
AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen
Ich habe jetzt mal folgendes gemacht:
Delphi-Quellcode:
OK, das funktioniert schon mal. Habe als DOMVendor OmniXML angegeben. Gibt es hier evtl. anderweitige Empfehlungen?
procedure TF_Main.bnTestClick(Sender: TObject);
var Node: IXMLNode; procedure IterateChilds (ANode:IXMLNode); var subnode: IXMLNode; begin for var i := 0 to ANode.ChildNodes.Count-1 do begin subnode := ANode.ChildNodes[i]; if subnode.HasChildNodes then begin IterateChilds (Subnode); end else begin if subnode.Text = '{Betreff}' then begin subnode.Text := 'Dies ist der neue Betrefftext'; end; end; end; end; begin xmldoc.LoadFromFile('D:\Word\document.xml'); xmldoc.Active := True; for var L := 0 to xmldoc.ChildNodes.Count-1 do begin node := xmldoc.ChildNodes[L]; if node.HasChildNodes then begin IterateChilds (node); end else begin if node.Text = '{Betreff}' then begin node.Text := 'Dies ist der neue Betrefftext'; end; end; end; //xmldoc.SaveToStream(ms) end; Das schreibt Word da rein (Auszug mit" Hern Walter Müller ):
Code:
-<w:p w:rsidP="00386E60" w:rsidRDefault="00386E60" w:rsidR="00386E60" w14:textId="77777777" w14:paraId="2B1D1A28">
-<w:pPr> <w:spacing w:after="0"/> -<w:rPr> <w:rFonts w:hAnsi="Arial" w:ascii="Arial" w:cs="Arial"/> <w:lang w:val="de-DE"/> </w:rPr> </w:pPr> -<w:r> -<w:rPr> <w:rFonts w:hAnsi="Arial" w:ascii="Arial" w:cs="Arial"/> <w:lang w:val="de-DE"/> </w:rPr> <w:t>Herrn</w:t> </w:r> </w:p> -<w:p w:rsidP="00386E60" w:rsidRDefault="00386E60" w:rsidR="00386E60" w14:textId="77777777" w14:paraId="599B367F"> -<w:pPr> <w:spacing w:after="0"/> -<w:rPr> <w:rFonts w:hAnsi="Arial" w:ascii="Arial" w:cs="Arial"/> <w:lang w:val="de-DE"/> </w:rPr> </w:pPr> -<w:r> -<w:rPr> <w:rFonts w:hAnsi="Arial" w:ascii="Arial" w:cs="Arial"/> <w:lang w:val="de-DE"/> </w:rPr> <w:t>Walter Müller</w:t> </w:r> </w:p> |
AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen
Ich habe mal IterateChilds so abgeändert:
Delphi-Quellcode:
Leider beschwert Word sich über die Dokumentenstruktur und liest das Dokument nicht ein.
procedure IterateChilds (ANode:IXMLNode);
var addnode, subnode: IXMLNode; begin for var i := 0 to ANode.ChildNodes.Count-1 do begin subnode := ANode.ChildNodes[i]; if subnode.HasChildNodes then begin IterateChilds (Subnode); end else begin if subnode.Text = '{Betreff}' then begin subnode.Text := 'Dies ist der neue Betrefftext'; end; if subnode.Text = '{Adr_Alles}' then begin subnode.text := 'Herrn'; // First line subnode.AddChild('p').AddChild('r').AddChild('t').NodeValue := 'Walter Müller'; subnode.AddChild('p').AddChild('r').AddChild('t').NodeValue := 'Steinstraße 23'; subnode.AddChild('p').AddChild('r').AddChild('t').NodeValue := '53129 bonn'; end; end; end; end; |
AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
So gehts schon mal besser, Ergebnis siehe Anlage.
if subnode.Text = '{Adr_Alles}' then begin
subnode.text := '53129 Bonn'; // First line subnode.AddChild('w:p').AddChild('w:rPr').AddChild('w:t').NodeValue := 'Herrn'; subnode.AddChild('w:p').AddChild('w:rPr').AddChild('w:t').NodeValue := 'Walter Müller'; subnode.AddChild('w:p').AddChild('w:rPr').AddChild('w:t').NodeValue := 'Steinstraße 23'; end; Problem sind nur die Abstände. Vermute aber mal, das kriege ich hin wenn ich die Zeile mit {Adr_Alles} richtig formatiere (also ohne Abstand vorher oder nachher. |
AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen
Frage: Wie mache ich es, ein Tag anzuhängen, das kein öffnendes Tag hat:
Ich möchte, das es so aussieht: <w:t>Walter Müller</w:t><w:br/> Aber Addchild erzeugt ja immer ein öffnendes und schließendes Tag? Also wie kriege ich <w:br/> (für Softbreak) da noch dran? |
AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen
Wie die XML-Komponente mit leeren Tags/Nodes umgeht, dürfte man in deren Optionen finden.
Beim Lesen sollte dem anderen Programm es aber auch egal sein, ob es <br></br> oder <br/> ist. Soll das mehrzeilige mehrzeilig bleiben, dann die Zeilenumbrüche mit irgendwas maskieren, bzw. hier entsprechend ein HTML-Tag ala <BR/> einfügen. Alternativ den Text in CDATA einkapseln. |
AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen
Was auch doof ist - und mir insofern die XML-Klasse wohl doch nicht hilft - ist, dass Word in seinem inneren XML-Gefüge den Text umformatiert, wenn man den Platzhalter bearbeitet (z.B. Zeilenabstand oder Font) und dann das so aussieht:
Code:
D.H. die "{" und "}" werden von meinem Platzhalter-Text getrennt und subnote.text gibt mir eben nur "Adr_Alles" zurück...
- <w:r w:rsidRPr="005E0480">
- <w:rPr> <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial" /> <w:iCs /> <w:lang w:val="de-DE" /> </w:rPr> <w:t>{</w:t> </w:r> <w:proofErr w:type="spellStart" /> - <w:r w:rsidRPr="005E0480"> - <w:rPr> <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial" /> <w:iCs /> <w:lang w:val="de-DE" /> </w:rPr> <w:t>Adr_Alles</w:t> </w:r> <w:proofErr w:type="spellEnd" /> - <w:r w:rsidRPr="005E0480"> - <w:rPr> <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial" /> <w:iCs /> <w:lang w:val="de-DE" /> </w:rPr> <w:t>}</w:t> </w:r> </w:p> Bleibt wohl nur übrig, dass ich vorher prüfe, ob ein "{" vorkam und wenn nur ein "Adr_Alles" kommt, ich zurück iteriere und "{" da lösche und auch weiter interiere und dann das "}" lösche. Ganz schön umständlich... |
AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen
Zitat:
Wieso Platzhalter im Text? Das Word Format hat Doch eigene Felder für so etwas? Ich will jetzt nicht nachschauen aber für mich klingt das nicht plausibel. Benutze die Möglichkeiten die dafür vorgesehen sind. Ansonsten investiere in WPTools und Julian wird Dir helfen... Was ich damit sagen will, selber das XML so zu schreiben das Word "immer" damit klarkommt ist schon ambitioniert Aber nur meine Meinung Gruss Fritz |
AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen
Zitat:
Aber Dein Hinweis hat mich auf eine Idee gebracht: Word oder Libre Office mögen zwar den Dokumententext wie oben beschrieben zerhackseln (oh mann, was ist das ein ineffizientes Textformat, soviel Müll da drin) aber interne Bookmark-Namen natürlich nicht. Insofern habe ich meine Strategie gewechselt, dass ich in die .dotx bzw. .ott Vorlagen Textmarken einfügen und die ganzen Textmarken (die ich an den passenden Namen erkenne) durch Text ersetze. Nach meinen ersten Tests funktioniert das - mit meiner ursprünglichen Suchen und ersetzen Methode - recht gut...:-D |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:13 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz