![]() |
[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:
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:
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?
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; Oder sollte ich doch einfach MSXML4.0 nachrüsten? |
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:
Für den Parser benutzte dann IXMLDOMDocument2, da kannste 4.0 oder 6.0 erstellen ( aber dann halt nur die 4.0er Funktionen nutzen).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 die SchemaCollection benutzte dann IXMLDOMSchemaCollection2, da kannste dann entweder die 4.0 oder 6.0 Version erstellen.
Delphi-Quellcode:
Da du ja dann die Interfaces benutzt und beide Versionen mit denen kompatibel sind, sollte es dabei keine Probleme geben :)
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; Falls ich mich nicht irre ^_° MfG Alaitoc |
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. |
Re: [MSXML + XSD-Validation] Welche MSXML Version?
Zitat:
(Ansonsten gäbe es ja noch "Late Binding", aber das ist hier überflüssig) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:22 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