【问题标题】:How Check if a XML file if well formed using delphi?如果使用delphi格式正确,如何检查XML文件?
【发布时间】:2011-04-02 01:49:30
【问题描述】:

如何检查 xml 文件是否格式正确,没有无效字符或标签?

例如,考虑这个 xml:

<?xml version="1.0"?>
<PARTS>
   <TITLE>Computer Parts</TITLE>
   <PART>
      <ITEM>Motherboard</ITEM>
      <MANUFACTURER>ASUS</MANUFACTURER>
      <MODEL>P3B-F</MODEL>
      <COST> 123.00</COST>
   </PART>
   <PART>
      <ITEM>Video Card</ITEM>
      <MANUFACTURER>ATI</MANUFACTURER>
      <MODEL>All-in-Wonder Pro</MODEL>
      <COST> 160.00</COST>
   </PART>
</PARTSx>

最后一个标签&lt;/PARTSx&gt;必须是&lt;/PARTS&gt;

【问题讨论】:

  • 您的标题谈到了验证,但正文似乎只是关于格式良好的 XML。这是两个不同的东西。如果没有 DTD 或 XSD,您就无法验证 XML。你确定你知道你在问什么吗?
  • 同意 Rob,您需要先阅读 well formed XML,然后再阅读 Valid XML(您需要 XML SChema)。任何 XML 解析器都可以检查格式是否正确或

标签: xml delphi


【解决方案1】:

可以使用MSXML DOMDocument返回的IXMLDOMParseError接口

此接口返回一系列属性,可帮助您识别问题。

  • errorCode 包含最后一个解析错误的错误代码。只读。
  • filepos 包含发生错误的绝对文件位置。只读。
  • line 指定包含错误的行号。只读。
  • linepos 包含发生错误的行中的字符位置。
  • reason 描述错误的原因。只读。
  • srcText 返回包含错误的行的全文。只读。
  • url 包含包含最后一个错误的 XML 文档的 URL。只读。

检查这两个使用 MSXML 6.0 的函数(你也可以使用其他版本)

uses
  Variants,
  Comobj,
  SysUtils;

function IsValidXML(const XmlStr :string;var ErrorMsg:string) : Boolean;
var
  XmlDoc : OleVariant;
begin
  XmlDoc := CreateOleObject('Msxml2.DOMDocument.6.0');
  try
    XmlDoc.Async := False;
    XmlDoc.validateOnParse := True;
    Result:=(XmlDoc.LoadXML(XmlStr)) and (XmlDoc.parseError.errorCode = 0);
    if not Result then
     ErrorMsg:=Format('Error Code : %s  Msg : %s line : %s Character  Position : %s Pos in file : %s',
     [XmlDoc.parseError.errorCode,XmlDoc.parseError.reason,XmlDoc.parseError.Line,XmlDoc.parseError.linepos,XmlDoc.parseError.filepos]);
  finally
    XmlDoc:=Unassigned;
  end;
end;

function IsValidXMLFile(const XmlFile :TFileName;var ErrorMsg:string) : Boolean;
var
  XmlDoc : OleVariant;
begin
  XmlDoc := CreateOleObject('Msxml2.DOMDocument.6.0');
  try
    XmlDoc.Async := False;
    XmlDoc.validateOnParse := True;
    Result:=(XmlDoc.Load(XmlFile)) and (XmlDoc.parseError.errorCode = 0);
    if not Result then
     ErrorMsg:=Format('Error Code : %s  Msg : %s line : %s Character  Position : %s Pos in file : %s',
     [XmlDoc.parseError.errorCode,XmlDoc.parseError.reason,XmlDoc.parseError.Line,XmlDoc.parseError.linepos,XmlDoc.parseError.filepos]);
  finally
    XmlDoc:=Unassigned;
  end;
end;

【讨论】:

    【解决方案2】:

    您如何创建/接收 XML?任何明智的解析器都会捕捉到这一点。

    例如,使用OmniXML

    uses
      OmniXML;
    
    type
      TForm1=class(TForm)
        Memo1: TMemo;
        //...
      private
        FXMLDoc: IXMLDocument;
        procedure FormCreate(Sender: TObject);
        procedure CheckXML;
      end;
    
    implementation
    
    uses
      OmniXMLUtils;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      // Load your sample XML. Can also do Memo1.Text := YourXML
      Memo1.Lines.LoadFromFile('YourXMLFile.xml');
    end;
    
    procedure TForm1.CheckXML;
    begin
      FXMLDoc := CreateXMLDoc;
      // The next line raises an exception with your sample file.
      XMLLoadFromAnsiString(FXMLDoc, Memo1.Text); 
    end;
    

    【讨论】:

    • Ken,我正在处理许多由外部应用程序生成的 xml 文件,有时它们具有无效的字符或未终止的标签。
    • @Salvador:收到后如何处理?正如我所说,任何体面的解析器都会为格式错误或无效的文件引发异常;如果你用自己的代码解析它们,你不应该。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 2016-04-03
    • 2017-02-11
    • 1970-01-01
    相关资源
    最近更新 更多