AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Cross-Platform-Entwicklung Delphi Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen
Thema durchsuchen
Ansicht
Themen-Optionen

Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen

Ein Thema von Harry Stahl · begonnen am 16. Feb 2021 · letzter Beitrag vom 16. Feb 2021
Antwort Antwort
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#1

Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen

  Alt 16. Feb 2021, 15:05
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.
Angehängte Grafiken
Dateityp: jpg word.jpg (73,4 KB, 29x aufgerufen)
Angehängte Dateien
Dateityp: xml content.xml (10,3 KB, 5x aufgerufen)
Dateityp: xml document.xml (11,4 KB, 3x aufgerufen)
  Mit Zitat antworten Zitat
bcvs

Registriert seit: 16. Jun 2011
730 Beiträge
 
Delphi 12 Athens
 
#2

AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen

  Alt 16. Feb 2021, 16:41
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.
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#3

AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen

  Alt 16. Feb 2021, 17:01
Ich habe jetzt mal folgendes gemacht:
Delphi-Quellcode:
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;
OK, das funktioniert schon mal. Habe als DOMVendor OmniXML angegeben. Gibt es hier evtl. anderweitige Empfehlungen?

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>

Geändert von Harry Stahl (16. Feb 2021 um 17:17 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#4

AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen

  Alt 16. Feb 2021, 17:43
Ich habe mal IterateChilds so abgeändert:

Delphi-Quellcode:
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;
Leider beschwert Word sich über die Dokumentenstruktur und liest das Dokument nicht ein.
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#5

AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen

  Alt 16. Feb 2021, 17:58
Delphi-Quellcode:
 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;
So gehts schon mal besser, Ergebnis siehe Anlage.

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.
Angehängte Grafiken
Dateityp: png result1.png (5,4 KB, 10x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#6

AW: Platzhalter in XML-Datei durch (mehrzeiligen) Text ersetzen

  Alt 16. Feb 2021, 18:10
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?
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:46 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