Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Seltsames Memo LoadFomFile inculde Phänomen (https://www.delphipraxis.net/182133-seltsames-memo-loadfomfile-inculde-phaenomen.html)

Ajintaro 2. Okt 2014 20:08

Seltsames Memo LoadFomFile inculde Phänomen
 
Hallo DP !

Ich habe ein recht seltsames Verhalten, welches ich mir nicht erklären kann. Ich validiere eine XML gegen eine XSD Datei. Das funktioniert zwar prima, allerdings NUR wenn die XSD Datei per OpenTextFileDialog in das Memo geladen wird. Denn dann wird auch die "include" Zeile berücksichtigt.


Funktioniert:
Delphi-Quellcode:
procedure TFmain.button_open_xsdClick(Sender: TObject);
begin
 open_xmlorxsd.InitialDir := ExtractFilePath(Application.ExeName);
 open_xmlorxsd.filter := '.xsd';
 open_xmlorxsd.filename := '*.xsd';
 if open_xmlorxsd.Execute then memo_xsd.Lines.LoadFromFile(open_xmlorxsd.FileName);
end;

if validate_xml_memo(memo_xml.Lines.Text,memo_xsd.Lines.Text) = TRUE then Showmessage('Hurra');
Funktioniert nicht:
Delphi-Quellcode:
xsd := ExtractFilePath(Application.ExeName) + filename + '.xsd';
memo_xsd.lines.loadfromfile(xsd);
if validate_xml_memo(memo_xml.Lines.Text,memo_xsd.Lines.Text) = TRUE then Showmessage('Hurra');
XSD:
Code:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.hoppsassa.com/rr/schna/Types" elementFormDefault="qualified" targetNamespace="http://www.hoppsassa.com/rr/schna/Types">
  <xs:include schemaLocation="Types_Enhanced.xsd"/>
  <xs:element type="tns:Cool" name="Cool"/>
</xs:schema>
Wie gesagt der Pfad zu beiden XSD Dateien ist in beiden Fällen gleich. Per OpenTextFileDialog wird die include Zeile berücksichtigt, wenn ich die Datei einfach per LoadFromFile lade, wird die include Datei nicht gefunden.

Woran liegt das?

mjustin 2. Okt 2014 20:11

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Zitat:

Zitat von Ajintaro (Beitrag 1274677)
Woran liegt das?

Vermutlich setzt der Dialog das aktuelle Verzeichnis, dagegen wird bei LoadFromFile kein Verzeichniswechsel durchgeführt.
Das include gibt einen Pfad "relativ zum aktuellen Verzeichnis" an.

himitsu 2. Okt 2014 22:16

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Nicht vermutlich, sondern mit Sicherheit.
Darum soll man auch nicht mit relativen Pfaden arbeiten.

Und dieses
Delphi-Quellcode:
if myboolean = True then
ist auch eine geährliche Angelegenheit.


Am Besten wäre es, wenn man dem validate_xml_memo einen Pfad für Include-Dateien mitgeben könnte,
oder man muß ebenfalls am aktuellen Pfad rumfummeln.

Und warum heißt das eigentlich Memo? (validate_xml_memo)
Die Methode bekommt zwei Strings und keine Memos rein.

Zitat:

InitialDir := ExtractFilePath
Fällt dir was auf?

Zitat:

open_xmlorxsd.filter := '.xsd';
open_xmlorxsd.filename := '*.xsd';
Der Dialog behandelt doch nur die .XSD?
Dann kannst du die Parameter auch gleich alle im OI angeben.
Aber:
Dein FileName ist falsch, denn darin hat ein * nichts zu suchen. (leer lassen, einen richtigen DefaulFileNamen reinschreiben oder auf leer setzen, um den letzten Aufruf zurückzusetzen)
Der Filter hält sich auch nicht an die Definition. (schau mal in die OH)
Dann könnte man eventuell noch FilterIndex und DefaultFilter setzen.



Und nein, deine Fehleranalyse ist falsch, denn am LoadFromFile liegt es nicht, da es immer richtig funktioniert, egal ob mit oder ohne OpenDialog.
Das Problem liegt ausschließlich in deinem validate_xml_memo.

Ajintaro 2. Okt 2014 22:43

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Hi,

Okay habe den Filter abgändert:
Delphi-Quellcode:
open_xmlorxsd.filter := 'XSD schemas (*.xsd)|*.XSD';
die Funktion sieht wie folgt aus:

Delphi-Quellcode:
{++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// validate_xml_memo
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
Function validate_xml_memo(xml,xsd: string):Boolean;

  procedure AddParseError(E: IXMLDOMParseError);
  begin
    if E.errorCode <> 0 then
    begin
     Showmessage('Validation Error: '+E.reason+#13#10+E.srcText)
    end else result:=TRUE;
  end;

var
  Doc: IXMLDOMDocument2;
  Schema: IXMLDOMDocument2;
  SchemaCache: IXMLDOMSchemaCollection;
  sNameSpace: String;
begin
  try
    // Load XML document
    Doc := CoDOMDocument60.Create;
    Doc.async := False;
    Doc.resolveExternals := True;
    Doc.validateOnParse := True;

    if not Doc.loadXML(xml) then
    begin
      AddParseError(Doc.parseError);
      Exit;
    end;

    // Load schema
    Schema := CoDOMDocument60.Create;
    Schema.async := False;
    Schema.resolveExternals := True;
    Schema.validateOnParse := True;

    if not Schema.loadXML(xsd) then
    begin
      AddParseError(Schema.parseError);
      Exit;
    end;

    // put in schema cache
    SchemaCache := CoXMLSchemaCache60.Create;
    sNameSpace := VarToStr(Schema.documentElement.getAttribute('targetNamespace'));
    SchemaCache.add(sNameSpace, Schema); //load schema with the correct namespace

    // assign schema cache to a document
    Doc.schemas := SchemaCache;

    // Validate
    AddParseError(Doc.validate);
    result:=TRUE;
  except
    on E: Exception do
      Showmessage(E.message);
  end;
end;
Die XSD Dateien liegen in einem benutzerdefinierten Ordner, dessen Pfad beim Starten des Programms aus einer ini gelesen wird.

Sir Rufo 3. Okt 2014 01:33

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Nur mal so am Rande

Was möchtest du mit
Delphi-Quellcode:
try
  ...
except
  on E: Exception do
    Showmessage(E.message);
end;
erreichen?

Soll bei einer Exception ein Dialog mit der Fehlermeldung erscheinen?
Dann entferne diesen
Delphi-Quellcode:
try .. except
Block, denn die Anwendung macht das von ganz alleine!

Was du jetzt hast ist eine Funktion, die bei einer Exception die Exception-Message ausgibt (der Exception-Typ fällt unter den Tisch) und dann irgendeinen nicht kontrollierbaren Rückgabewert an den Aufrufer zurückliefert.

Wenn du Pech hast, dann siehst du diese Fehlermeldung und direkt danach die Meldung "Hurra".

Wem soll das denn nun etwas sagen?

Irgendwie gibt deine Funktion egal wie nur gesichert ein
Delphi-Quellcode:
True
heraus, ein
Delphi-Quellcode:
False
wird nie explizit gesetzt. Wahrscheinlich musst du deswegen auch den Rückgabewert auf
Delphi-Quellcode:
True
prüfen, sonst siehst du sehr selten Hurra.

himitsu 3. Okt 2014 02:13

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Noch besser, wenn vorher der Code abgebrochen ist, das AddParseError aufrief und der Fehlercode zufällig 0 ist, dann gibt die Funktion auch True zurück, obwohl garnicht alles abgearbeitet wurde.
Und AddParseError fügt nichts irgendwo hinzu, sondern gibt nur eine Fehlermelung aus, also eher ein ShowParseError. :stupid:

Zitat:

Zitat von Sir Rufo (Beitrag 1274689)
Irgendwie gibt deine Funktion egal wie nur gesichert ein
Delphi-Quellcode:
True
heraus, ein
Delphi-Quellcode:
False
wird nie explizit gesetzt.

Ein guter beweis, daß sich niemand die Compilermeldungen ansieht und auf das hört, was man ihm dort sagt.

Zitat:

sonst siehst du sehr selten Hurra.
Eher andersrum, er bekommt zu 99,3% ein False fehlerhaft als True (<>0) geliefert
und zu 0,4% wird ein "False" genau das True (=1) ergeben.

Dejan Vu 3. Okt 2014 07:40

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Zitat:

Zitat von himitsu (Beitrag 1274691)
Ein guter beweis, daß sich niemand die Compilermeldungen ansieht und auf das hört, was man ihm dort sagt.

Und das ist der Beweis, das viele Programmierer wirklich glauben, das NOT Alle = Niemand ist. Einer liest sie nicht und Du folgst daraus 'niemand'. Tss Tss Tss. Richtig wäre der Satz: 'Ein guter Beweis, das nicht Alle die Compilermeldungen anschauen' was wiederum banal ist, denn wenn eins im Leben immer gilt, dann, das es kein 'alle' und kein 'immer' gibt.(*)

Wollen wir das mit dem 'beweisen' vielleicht nochmal üben? Und gleich danach, oder besser davor noch, Grundlagen der Logik? :lol:

(*) Und der, der mich jetzt auf den Widerspruch hinweist und dabei den Witz nicht kapiert, kriecht'n Keks.

Was aber natürlich stimmt, ist, das man die Warnhinweise des Compilers ernst nehmen und (fast) alles daran setzen sollte, diese auf 0 zu bekommen ohne sie auszuschalten.

PS: Und 'ja', mir ist langweilig :stupid:

Sailor 3. Okt 2014 09:22

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
OT: @himitsu

Und dieses
Delphi-Quellcode:
if myboolean = True then
ist auch eine geährliche Angelegenheit.

Könntest Du mal aufhören, ständig diesen Unsinn zu posten?

mkinzler 3. Okt 2014 09:41

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Zitat:

Zitat von Sailor (Beitrag 1274700)
OT: @himitsu

Und dieses
Delphi-Quellcode:
if myboolean = True then
ist auch eine geährliche Angelegenheit.

Könntest Du mal aufhören, ständig diesen Unsinn zu posten?

Nein, weil es kein Unsinn ist!

Uwe Raabe 3. Okt 2014 09:48

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Zitat:

Zitat von Sailor (Beitrag 1274700)
OT: @himitsu

Und dieses
Delphi-Quellcode:
if myboolean = True then
ist auch eine geährliche Angelegenheit.

Könntest Du mal aufhören, ständig diesen Unsinn zu posten?

Ich bin mir jetzt nicht sicher, ob du die Aussage oder den Tippfehler meinst. Für ersteren Fall habe ich hier eine kleine Prozedur, die den Unterschied demonstriert:

Delphi-Quellcode:
procedure Main;
var
  myBoolean: Boolean;
  I: Integer;
begin
  I := 2;
  Move(I, myBoolean, Sizeof(myBoolean));
  if myBoolean = (myBoolean = true) then
    Writeln('OK!')
  else
    Writeln('Shit!');
end;

himitsu 3. Okt 2014 10:11

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Wieso hab ich das gepostet?

Hab es "gefährlich" genannt und genug Gründe erwähnt es besser sowas nicht zu machen, was Uwe auch grade nochmal anschaulich demonstriert hat. :roll:
(bis auf spezielle Sonderfälle macht man sowas einfach nicht, welche hier nicht vorliegen, wenn man die Funktion reparieren würde)

True ist nunmal nicht als 1 (die Konstante True) deklariert, sondern als <>0, was die automatische Booleanauswertung ordentlich berücksichtigt.

Sailor 3. Okt 2014 10:24

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Wer so was macht, gehört abgemahnt und im Wiederholungsfall gefeuert.
Oder macht Ihr auch das?

Code:
PROCEDURE Main;
 VAR
  myString: String;
         i: Integer;

 BEGIN
  Move('1234',i,4);
  IF i = 1234 
   THEN Writeln('OK!')
   ELSE Writeln('Shit!')
 END;
Man kann mit einem Hammer Nägel in die Wand oder sich auf den Daumen hauen. Ich ziehe ersteres vor. Na ja, war OT und damit Ende Gelände.

mkinzler 3. Okt 2014 10:29

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
War ja nur ein Beispiel. Eine weiteres wäre der andere Wert für die Konstante True in der Sprache C, also auch alle Rückgaben von WinAPI Funktionen.

Die Konstante hat in Delphi den Wert 1 in C das binäre Komplement zu False ( 0) nämlich -1!
Und 1 ist was anderes als -1!

als True <> True.

Sailor 3. Okt 2014 10:37

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
@Himitsu:
True ist nunmal nicht als 1 (die Konstante True) deklariert, sondern als <>0, was die automatische Booleanauswertung ordentlich berücksichtigt.

Nein, True ist nicht als <> 0 deklariert, sondern in Delphi so implementiert. True ist True und nicht 0 oder 3.5 oder HmstlBmpl. Implementierungsdetails haben in einem Programm nichts zu suchen. Das fällt einem sofort auf die Füße, wenn man z.B. unter Delphi entwickelt und dann auf andere Pascalsysteme portiert. Haben wir jahrelang so gemacht, erfolgreich. Mit obigen Tricks wären wir wohl ziemlich auf die Nase gefallen.

@MKinzler
Wenn ich mich außerhalb meiner Sprache bewege, muß ich eben aufpassen. Lies mal Integerwerte ein, die von einer IBM/360 stammen. In C gibt es im Unterschied zu Pascal keinen Wert True, das ist dort ein
#define true -1.

Aber nu is wirklich gut.

Ajintaro 3. Okt 2014 13:59

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Hi,

vielen Dank für eure Impulse. Meine Validierungsfunktion soll bei fehlerfreier Validierung TRUE zurückgeben und ansonsten FALSE. Ich dachte mit dem try-Block kann ich genau das erreichen. Aber jetzt frage ich mich, ob ich die Funktion nicht grundlegend ändern sollte.


Allerdings haben wir uns etwas vom Kurs abbringen lassen :)
Ich bin mir jetzt immer noch nicht sicher, wie ich den bekannten Pfad der includes so setzen kann, damit diese auch Berücksichtigung findet.

Läuft nicht:
Delphi-Quellcode:
xsd := 'C:\test.xsd';
memo_xsd.Lines.LoadFromFile(xsd);
//do validation...
Läuft:
Delphi-Quellcode:
if OpenTextFileDialog1.Execute then memo_xsd.Lines.LoadFromFile(OpenTextFileDialog1.FileName);
//do validation...
Wie mjustin bereits erwähnt hat, wird beim Benutzen des opendialogs "das Verzeichnis" richtig gesetzt, während bei LoadFromFile dies nicht der Fall ist. Was macht denn der opendialog im Detail anders?

Uwe Raabe 3. Okt 2014 14:21

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
Zitat:

Zitat von Ajintaro (Beitrag 1274725)
Wie mjustin bereits erwähnt hat, wird beim Benutzen des opendialogs "das Verzeichnis" richtig gesetzt, während bei LoadFromFile dies nicht der Fall ist. Was macht denn der opendialog im Detail anders?

Lies dir mal die Hilfe zu
Delphi-Quellcode:
ofNoChangeDir
in
Delphi-Quellcode:
TOpenOptions
durch: http://docwiki.embarcadero.com/Libra...s.TOpenOptions

Dann probier dein Beispiel mal mit beiden Einstellungen aus.

Ajintaro 3. Okt 2014 14:49

AW: Seltsames Memo LoadFomFile inculde Phänomen
 
:coder2:

Ah jetzt ! Uwe, der Hinweis war Gold wert ! Das Problem liegt daran, dass der OpenDialog das Arbeitsverzeichnis wechselt - das hat vermutlich auch mjustin gemeint. Ein kleines
Delphi-Quellcode:
SetCurrentDir
behebt das kleine, nervige Problem :-)

:dp:


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz