Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Zeichen in XML ersetzen
SnuSnu - Fr 20.03.09 12:40
Titel: Zeichen in XML ersetzen
Hallo,
ich habe ein kleines Problem mit dem CDATA Tag in meiner xml. Mit den IXMLDocument und IDOMDocument Units erstelle ich wie folgt ein XML Dokument:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115:
| var lXMLDocument: IXMLDocument; iXMLDom : IDOMDocument; lNode: IXMLNode; lNode2: IXMLNode; lNode3: IXMLNode; lNode4: IXMLNode; streamValidate : TStringStream; begin if not (edtRole.Text <> '') then begin MessageDlg('Bitte geben Sie eine Benutzergruppe an.', mtInformation, [mbOK], 0); edtRole.SetFocus; exit; end; if not (edtKurs.Text <> '') then begin MessageDlg('Bitte geben Sie eine Kurs ID an.', mtInformation, [mbOK], 0); edtKurs.SetFocus; exit; end;
lXMLDocument := newXMLDocument; lXMLDocument.Options := [doNodeAutoCreate, doAutoSave]; lXMLDocument.ParseOptions := []; lXMLDocument.Encoding := 'ISO-8859-1'; lXMLDocument.Active := True;
lNode := lXMLDocument.AddChild('Users');
cdsPersonal.First; try while not cdsPersonal.Eof do begin
if cdsPersonal.FieldByName('Checked').AsInteger = cnsCdsCheckedFalse then begin cdsPersonal.Next; continue; end;
lNode2 := lNode.AddChild('User'); lNode2.Attributes['Id'] := cdsPersonal.FieldByName('PersonalI3D').AsString; lNode2.Attributes['Language'] := 'de'; lNode2.Attributes['Action'] := 'Insert';
lNode3 := lnode2.AddChild('Active'); lNode3.NodeValue := '@@cdatastart true @@cdataende';
lNode3 := lnode2.AddChild('Role'); lNode3.Attributes['Id'] := '_1'; lNode3.Attributes['Type'] := 'Global'; lNode3.Attributes['Action'] := 'Assign'; lNode3.NodeValue := edtRole.Text;
lNode3 := lnode2.AddChild('Role'); lNode3.Attributes['Id'] := '_2'; lNode3.Attributes['Type'] := 'Global'; lNode3.Attributes['Action'] := 'Assign'; lNode3.NodeValue := 'il_crs_member_' + edtKurs.Text;
lNode3 := lnode2.AddChild('Login'); lNode3.NodeValue := cdsPersonal.FieldByName('Name').AsString;
lNode3 := lnode2.AddChild('Password'); lNode3.Attributes['Type'] := 'ILIAS3'; lNode3.NodeValue := cdsPersonal.FieldByName('Vorname').AsString;
lNode3 := lnode2.AddChild('Gender'); lNode3.NodeValue := '';
lNode3 := lnode2.AddChild('Firstname'); lNode3.NodeValue := cdsPersonal.FieldByName('Vorname').AsString;
lNode3 := lnode2.AddChild('Lastname'); lNode3.NodeValue := cdsPersonal.FieldByName('Name').AsString;
lNode3 := lnode2.AddChild('Email'); lNode3.NodeValue := cdsPersonal.FieldByName('Email').AsString;
cdsPersonal.Next; end; finally cdsPersonal.First; end;
streamValidate := TStringStream.Create(EmptyStr); lXMLDocument.SaveToStream(streamValidate); lXMLDocument.LoadFromStream(ValidateXML(streamValidate));
fXMLDocument := lXMLDocument;
if SelectDirectory('Verzeichnis auswählen:', '', strPath ) then begin strPath := IncludeTrailingBackslash(strPath); end;
SaveFile(StrPath);
actSchliessen.Execute; |
Da diese keine CDATA Tags unterstützen, dachte ich mir ich speichere die XML in einen Stream und lese diesen Stream in einen String. Dort werden dann Textmarken ersetzt um dieses CDATA reinubekommen :
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| function TdlgPersonalInsIlias.ValidateXML(var Stream: TStringStream): TStringStream; var strStream : String; StreamResult : TStringStream; begin try strStream := Stream.DataString;
strStream := StringReplace(strStream, '''', '', [rfReplaceAll]); strStream := StringReplace(strStream, '#$D#$A', '', [rfReplaceAll]);
strStream := StringReplace(strStream, '@@cdatastart', '<![CDATA[', [rfReplaceAll]); strStream := StringReplace(strStream, '@@cdataende', ']]>', [rfReplaceAll]);
StreamResult := TStringStream.Create(strStream); StreamResult.Position := 0; Result := StreamResult; finally if assigned(StreamResult) then FreeAndNil(StreamResult); end; end; |
Komischerweise wird mir in den String ein ' Zeichen eingefügt, das ich so auch nicht herausbekommen. Genauso wenig das '#$D#$A'.
Dies ist auch der Grund für den Error beim erstellen der XML.
Meine Frage hierzu:
Wie bekomme ich diese Zeichen heraus oder wie kann ich ohne größeren Aufwand und ohne abändern/ersetzen der Units einen CDATA Tag reinbekommen ?
Bedanke mich schonmal im Vorraus für jeglichen Mühen eurerseits =)
gruß Snu
ffgorcky - Sa 23.05.09 16:35
Also ich denke, dass man die Zeilenumbrüche so ersetzen kann:
Delphi-Quelltext
1:
| strStream := StringReplace(strStream, #13#10, '', [rfReplaceAll]); |
Damit würde dann
so ein Text so aussehen:
Delphi-Quelltext
1:
| strStream='Damit würde dannso ein Text so aussehen:' |
Also wäre es besser, wenn man denn dort auch als Ersatz nicht einfach einen Leerstring setzt, sondern wieder ein Leerzeichen.
...Wobei auch ab und an nur die
#10 genutzt werden muss, da dann kein Ende der Zeile (also
#13) vermerkt ist, sondern nur der Zeilenumbruch (also
#10) - warum auch immer.
Das müsste dann ja auch mit Deinem
#$D#$A genauso gehen, denn ich meine, dass das das gleiche ist, nur eben anders bezeichnet. (Da steht wahrscheinlich das Zeichen $ für die zehner-1, das D für 3 und das $A für 0[=Null].)
SvenAbeln - Sa 23.05.09 18:48
ffgorcky hat folgendes geschrieben : |
Das müsste dann ja auch mit Deinem #$D#$A genauso gehen, denn ich meine, dass das das gleiche ist, nur eben anders bezeichnet. (Da steht wahrscheinlich das Zeichen $ für die zehner-1, das D für 3 und das $A für 0[=Null].) |
Nein das $ steht für die Darstellung der Zahl als Hexadezimal und damit A = 10 und D = 13.
SnuSnu hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| [...] StreamResult := TStringStream.Create(strStream); StreamResult.Position := 0; Result := StreamResult; finally if assigned(StreamResult) then FreeAndNil(StreamResult); <---- Hier wird das Objekt zerstört und Result ist nun ungültig end; end; |
|
Wenn du ein Objekt als Result zurückgeben willst, darfst du es nicht innerhalb der Funktion wieder zerstören.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!