7

参照するスキーマに対して XML ファイルを検証しようとしています。(Delphi と MSXML2_TLB を使用。) コード (の関連部分) は次のようになります。

procedure TfrmMain.ValidateXMLFile;
var
    xml: IXMLDOMDocument2;
    err: IXMLDOMParseError;
    schemas: IXMLDOMSchemaCollection;
begin
    xml := ComsDOMDocument.Create;
    if xml.load('Data/file.xml') then
    begin
        schemas := xml.namespaces;
        if schemas.length > 0 then
        begin
            xml.schemas := schemas;
            err := xml.validate;
        end;
    end;
end;

これにより、キャッシュがロードされます ( schemas.length > 0) という結果になりますが、次の割り当てで例外が発生します。「XMLSchemaCache-schemacollections のみを使用できます。」

これについてどうすればよいですか?

4

4 に答える 4

1

BennyBechDkは正しい方向に進んでいる可能性がありますが、彼のコードにいくつか問題があり、以下で修正します。

uses Classes, XMLIntf, xmlDoc, SysUtils;

function IsValidXMLDoc(aXmlDoc: IXMLDocument): boolean;
var
  validateDoc: IXMLDocument;
begin
  result := false;  // eliminate any sense of doubt, it starts false period.
  validateDoc := TXMLDocument.Create(nil);
  try   
    validateDoc.ParseOptions := [poResolveExternals, poValidateOnParse];
    validateDoc.XML := aXmlDoc.XML;
    validateDoc.Active := true;
    Result := True;
  except
    // for this example, I am going to eat the exception, normally this
    // exception should be handled and the message saved to display to 
    // the user.
  end;
end;

システムで例外を発生させるだけの場合は、そもそもそれを関数にする理由はありません。

uses Classes, XMLIntf, XMLDoc, SysUtils;

procedure ValidateXMLDoc(aXmlDoc: IXMLDocument);
var
  validateDoc: IXMLDocument;
begin
  validateDoc := TXMLDocument.Create(nil);
  validateDoc.ParseOptions := [poResolveExternals, poValidateOnParse];
  validateDoc.XML := aXmlDoc.XML;
  validateDoc.Active := true;
end;

validateDocはインターフェースであるため、関数/プロシージャが終了するときに適切に破棄されます。自分で破棄を実行する必要はありません。ValidateXmlDocを呼び出しても例外が発生しない場合は、有効です。個人的には、最初の呼び出しであるIsValidXMLDocが好きです。これは、有効な場合はtrueを返し、そうでない場合はfalseを返します(それ自体の外部で例外を発生させません)。

于 2009-01-16T18:41:01.843 に答える
1

私はその欠点を解決するために Miel のソリューションに取り組みました。xml を 2 回開きます。1 回目は名前空間を取得するため、もう 1 回はスキーマ コレクションの作成後にファイルを検証するためです。わたしにはできる。IXMLDOMDocument2 は、一度開くとスキーマ プロパティの設定を受け入れないようです。

function TForm1.ValidXML2(const xmlFile: String;
  out err: IXMLDOMParseError): Boolean;
var
  xml, xml2, xsd: IXMLDOMDocument2;
  schemas, cache: IXMLDOMSchemaCollection;
begin
  xml := CoDOMDocument.Create;
  if xml.load(xmlFile) then
    begin
    schemas := xml.namespaces;
    if schemas.length > 0 then
      begin
      xsd := CoDOMDocument40.Create;
      xsd.Async := False;
      xsd.load(schemas.namespaceURI[0]);
      cache := CoXMLSchemaCache40.Create;
      cache.add(schemas.namespaceURI[1], xsd);
      xml2 := CoDOMDocument40.Create;
      xml2.async := False;
      xml2.schemas := cache;
      Result := xml2.load(xmlFile);
      //err := xml.validate;
      if not Result then
        err := xml2.parseError
      else
        err := nil;
      end;
    end;
于 2011-12-14T14:35:16.307 に答える
0

以前、次のコードを使用して XML ドキュメントを検証しました。

Uses
  Classes, 
  XMLIntf, 
  SysUtils;

Function ValidateXMLDoc(aXmlDoc: IXMLDocument): boolean;
var
  validateDoc: IXMLDocument;
begin
  validateDoc := TXMLDocument.Create(nil);

  validateDoc.ParseOptions := [poResolveExternals, poValidateOnParse];
  validateDoc.XML := aXmlDoc.XML;

  validateDoc.Active := true;
  Result := True;
end;
于 2009-01-16T08:18:23.777 に答える