Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi [MSXML + XSD-Validation] Welche MSXML Version? (https://www.delphipraxis.net/145554-%5Bmsxml-xsd-validation%5D-welche-msxml-version.html)

alzaimar 4. Jan 2010 10:04


[MSXML + XSD-Validation] Welche MSXML Version?
 
Hallo,

Ich habe hier gerade ein kleines Problem: Eine Anwendung, die sowohl under XP-Embedded als auch unter Vista laufen soll, muss XML-Dateien per XSD validieren. Ich habe dazu die Unit XMLValidate.PAS von CodeGear/Embarcadero geladen, die ihrerseits MSXML 4.0 voraussetzt. Die Anwendung war zunächst für XP-embedded konzipiert. Bei der vorliegenden Installation ist MSXML 4.0 installiert und die Anwendung funktioniert tadellos.

Die gleiche Anwendung funktioniert jedoch nicht mit Vista:
Zitat:

Zitat von Die Anwendung, gestartet unter Vista,
Class not registered, ClassID: {88D969C2-F192-11D4-A65F-0040963251E5}

Die GUID gehört zum Interface 'XMLSchemaCache40'. Offensichtlich ist MSXML 4.0 nicht installiert.

Frage: Soll ich wirklich extra dafür MSXML 4.0 nachträglich unter Vista installieren, oder geht das nicht auch anders ("Wenn MSXML 6.0 nimm diese Version, sonst die 4.0er"). Die Funktionalität selbst ist ja in 6.0 drin, denke ich mir, nur die GUIDs sind anders.

Der relevante Teil aus XMLValidate.Pas ist:

Delphi-Quellcode:
function LoadMSDom(const FileName: WideString): IXMLDOMDocument2;
begin
  Result := CoDOMDocument40.Create;  // <-------
  Result.async := False;
  Result.resolveExternals := True; //False;
  Result.validateOnParse := True;
  Result.load(FileName);
end;

{ Validate }

procedure InternalValidateXMLDoc(const Doc: IDOMDocument; const SchemaDoc: IXMLDOMDocument2; const SchemaNS: WideString);
var
  MsxmlDoc: IXMLDOMDocument2;
  SchemaCache: IXMLDOMSchemaCollection;
  Error: IXMLDOMParseError;
begin
  MsxmlDoc := DOMToMSDom(Doc);
  SchemaCache := CoXMLSchemaCache40.Create; // <<--------
  SchemaCache.add(SchemaNS, SchemaDoc);
  MsxmlDoc.schemas := SchemaCache;
  Error := MsxmlDoc.validate;
  if Error.errorCode <> S_OK then
    raise EValidateXMLError.Create(Error.errorCode, Error.reason);
end;
Ich müsste also zur Laufzeit irgendwie entscheiden, ob ich MSXML 4.0 oder 6.0 verwenden soll (das würde über eine einfache Prüfung gehen). Die Frage ist: WIE kann ich die *Verwendung* von V4.0 bzw. V6.0 transparent und elegant implementieren?
Oder sollte ich doch einfach MSXML4.0 nachrüsten?

Alaitoc 4. Jan 2010 10:19

Re: [MSXML + XSD-Validation] Welche MSXML Version?
 
Naja die Frage ist halt wie elegant du das haben willst, also das simpelste wäre ja nu wenn du diese Funktion ( die ich irgendwo aus dem Forum habe ) nutzt und die MSXML-Version überprüfst:

Delphi-Quellcode:

function ExpandEnvStr(const sInput: string): string;
const
  MAXSIZE = 32768;
begin
  SetLength(Result,MAXSIZE);
  SetLength(Result,ExpandEnvironmentStrings(pchar(sInput),
    @Result[1],length(Result)));
end;

function DoesMSXMLExist(CLASS_DOMDocument:TGUID): boolean;
var
  reg : TRegistry;
  s  : string;
begin
  Result := false;

  reg   := TRegistry.Create(KEY_READ);
  if(reg <> nil) then
    with reg do try
      RootKey := HKEY_CLASSES_ROOT;

      if(OpenKey('CLSID\' + GuidToString(CLASS_DOMDocument) +
        '\InProcServer32',false)) then
      try
        s     := ReadString('');
        Result := fileexists(ExpandEnvStr(s));
      finally
        CloseKey;
      end;
    finally
      Free;
    end;
end;

function CheckMSXML6:Boolean;
begin
  result:=DoesMSXMLExist(CLASS_DOMDocument60);
end;

function CheckMSXML4:Boolean;
begin
  result:=DoesMSXMLExist(CLASS_DOMDocument40);
end;

function CheckMSXML3:Boolean;
begin
  result:=DoesMSXMLExist(CLASS_DOMDocument30);
end;

function CheckMSXML2:Boolean;
begin
  result:=DoesMSXMLExist(CLASS_DOMDocument26);
end;
Für den Parser benutzte dann IXMLDOMDocument2, da kannste 4.0 oder 6.0 erstellen ( aber dann halt nur die 4.0er Funktionen nutzen).
Für die SchemaCollection benutzte dann IXMLDOMSchemaCollection2, da kannste dann entweder die 4.0 oder 6.0 Version erstellen.

Delphi-Quellcode:
function LoadMSDom(const FileName: WideString): IXMLDOMDocument2;
begin
  if CheckMSXML6 then
  begin
    Result := CoDOMDocument60.Create;  
  end
  else if CheckMSXML4 then
  begin
    Result := CoDOMDocument40.Create;
  end
  else
    // ERROR oder so
  end;
  Result.async := False;
  Result.resolveExternals := True; //False;
  Result.validateOnParse := True;
  Result.load(FileName);
end;

{ Validate }

procedure InternalValidateXMLDoc(const Doc: IDOMDocument; const SchemaDoc: IXMLDOMDocument2; const SchemaNS: WideString);
var
  MsxmlDoc: IXMLDOMDocument2;
  SchemaCache: IXMLDOMSchemaCollection2;
  Error: IXMLDOMParseError;
begin
  MsxmlDoc := DOMToMSDom(Doc);
  if CheckMSXML6 then
  begin
    SchemaCache := CoXMLSchemaCache60.Create;
  end
  else if CheckMSXML4 then
  begin
    Result := CoXMLSchemaCache40.Create;
  end
  else
    // ERROR oder so
  end;
  SchemaCache.add(SchemaNS, SchemaDoc);
  MsxmlDoc.schemas := SchemaCache;
  Error := MsxmlDoc.validate;
  if Error.errorCode <> S_OK then
    raise EValidateXMLError.Create(Error.errorCode, Error.reason);
end;
Da du ja dann die Interfaces benutzt und beide Versionen mit denen kompatibel sind, sollte es dabei keine Probleme geben :)
Falls ich mich nicht irre ^_°

MfG Alaitoc

alzaimar 4. Jan 2010 18:50

Re: [MSXML + XSD-Validation] Welche MSXML Version?
 
Hi Alaitoc,

Was für ein Service! Ich war heute morgen den ersten Tag wieder 'uff Aaabeet' und da setzt das Hirn noch aus bzw. kommt einfach nicht in die Gänge. Es laboriert noch an posttraumatischen Nachwehen der Silvesternacht...

Ich werd das morgen prüfen und einbauen: Ich denke, das sollte irgendwie klappen.

sirius 5. Jan 2010 07:50

Re: [MSXML + XSD-Validation] Welche MSXML Version?
 
Zitat:

Zitat von alzaimar
Ich denke, das sollte irgendwie klappen.

Natürlich sollte das klappen, dafür hat man doch die Ableitungen bei Interfaces eingeführt. Und wenn sich MS auch an ihre eigenen Vorgaben hält (veröffentlichtes Interface darf nie verändert nur erweitert=Ableitung werden), gibt es keine Probleme.


(Ansonsten gäbe es ja noch "Late Binding", aber das ist hier überflüssig)


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:24 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