蚊
蚊子
Unregistered / Unconfirmed
GUEST, unregistred user!
问题有点长,请耐心看完;
在MSXML 4.0 SDK中看到一个使用SAX入门例子,是VB写的。介绍如何使用XML的SAX(Simple API for XML)
http://msdn.microsoft.com/xml/articles/vbsax2jumpstart.exe
使用了XML中SAXXMLReader来读入Xml文档,实现了自己IVBSAXContentHandler和IVBSAXErrorHandler接口;
以下是有关文档;
SAXXMLReader
Coclass that implements the ISAXXMLReader interface. SAXXMLReader consumes the XML and throws
events to the handlers that you set for the reader. This example creates an instance of
SAXXMLReader, and then sets a ContentHandler and an ErrorHandler for receiving events from
the reader.
IVBSAXContentHandler
Catches events thrown by the reader. For this application, the ContentHandlerImpl class
implements the IVBSAXContentHandler interface. This application highlights the main events
received by the ContentHandler, including startDocument, endDocument, startElement, endElement,
and characters.
IVBSAXErrorHandler
Catches any errors raised during the read process. For this application, the ContentHandlerImpl
class also implements the IVBSAXErrorHandler interface. At this time, MSXML supports the
fatalError method only.
ContentHandlerImp.cls主要是实现了用户自己的IVBSAXContentHandler接口类,实现(重载?)接口的方法;
内容
Implements IVBSAXContentHandler
Private Sub IVBSAXContentHandler_startElement _
(strNamespaceURI As String, _
strLocalName As String, _
strQName As String, _
ByVal attributes As MSXML2.IVBSAXAttributes)
Dim i As Integer
Form1.Text2.text = Form1.Text2.text &
"<" &
strLocalName
For i = 0 To (attributes.length - 1)
Form1.Text2.text = Form1.Text2.text &
" " &
_
attributes.getLocalName(i) &
"=""" &
_
attributes.getValue(i) &
""""
Next
Form1.Text2.text = Form1.Text2.text &
">"
If strLocalName = "qu" Then
Err.Raise vbObjectError + 1, "ContentHandler.startElement", _
"Found element <qu>"
End If
End Sub
Private Sub IVBSAXContentHandler_endElement(strNamespaceURI As String, _
strLocalName As String, _
strQName As String)
Form1.Text2.text = Form1.Text2.text &
"</" &
strLocalName &
">"
End Sub
Private Sub IVBSAXContentHandler_characters(text As String)
text = Replace(text, vbLf, vbCrLf)
Form1.Text2.text = Form1.Text2.text &
text
End Sub
Private Property Set IVBSAXContentHandler_documentLocator(ByVal RHS As _
MSXML2.IVBSAXLocator)
End Property
Private Sub IVBSAXContentHandler_endDocument()
End Sub
Private Sub IVBSAXContentHandler_endPrefixMapping(strPrefix As String)
End Sub
Private Sub IVBSAXContentHandler_ignorableWhitespace(strChars As String)
End Sub
Private Sub IVBSAXContentHandler_processingInstruction(target As String, _
data As String)
Form1.Text2.text = Form1.Text2.text &
"<?" &
target &
" " _
&
data &
">"
End Sub
Private Sub IVBSAXContentHandler_skippedEntity(strName As String)
End Sub
Private Sub IVBSAXContentHandler_startDocument()
End Sub
Private Sub IVBSAXContentHandler_startPrefixMapping(strPrefix As String, _
strURI As String)
End Sub
在Form中的button click事件是这样的;
Private Sub Command1_Click()
Dim reader As New SAXXMLReader 'Reads the XML document
Dim contentHandler As New ContentHandlerImpl 'Receives parsing events
Dim errorHandler As New ErrorHandlerImpl 'Receive error events
Text2.text = ""
Set reader.contentHandler = contentHandler 'They work together
Set reader.errorHandler = errorHandler 'They also work together
On Error GoTo 10
reader.parseURL (Text1.text) 'Parse the document
'结果会输出到text2中
Exit Sub 'That's all, folks!
10: Text2.text = Text2.text &
"*** Error *** " &
Err.Number _
&
" : " &
Err.Description
End Sub
我现在要把这个例子翻译成Delphi,主Form很esay,但是翻译VB的类模块时就不知道怎么处理了。
Implements IVBSAXContentHandler
-------------------------------- >这句不懂怎么翻译到Delphi中;
我已经在Delphi中Import了Msxml.dll进来,在MSXML2_TLB.pas中;IVBSAXContentHandler是这样定义的;
IVBSAXContentHandler = interface(IDispatch)
['{2ED7290A-4DD5-4B46-BB26-4E4155E77FAA}']
procedure Set_documentLocator(const Param1: IVBSAXLocator)
safecall;
procedure startDocument
safecall;
procedure endDocument
safecall;
procedure startPrefixMapping(var strPrefix: WideString
var strURI: WideString)
safecall;
procedure endPrefixMapping(var strPrefix: WideString)
safecall;
procedure startElement(var strNamespaceURI: WideString
var strLocalName: WideString
var strQName: WideString
const oAttributes: IVBSAXAttributes)
safecall;
procedure endElement(var strNamespaceURI: WideString
var strLocalName: WideString
var strQName: WideString)
safecall;
procedure characters(var strChars: WideString)
safecall;
procedure ignorableWhitespace(var strChars: WideString)
safecall;
procedure processingInstruction(var strTarget: WideString
var strData: WideString)
safecall;
procedure skippedEntity(var strName: WideString)
safecall;
property documentLocator: IVBSAXLocator write Set_documentLocator;
end;
我想做的就是用自己的处理过程实现(重载?)这个接口中
procedure startElement(var strNamespaceURI: WideString
var strLocalName: WideString
var strQName: WideString
const oAttributes: IVBSAXAttributes)
safecall;
procedure endElement(var strNamespaceURI: WideString
var strLocalName: WideString
var strQName: WideString)
safecall;
procedure processingInstruction(var strTarget: WideString
var strData: WideString)
safecall;
大致程序如下;
unit Unit2;
interface
uses
Classes,MSXML2_TLB,unit1;
type
MySAXContentHandle = class
procedure startElement(var strNamespaceURI: WideString
var strLocalName: WideString;
var strQName: WideString
const oAttributes: IVBSAXAttributes)
safecall;
procedure endElement(var strNamespaceURI: WideString
var strLocalName: WideString;
var strQName: WideString)
safecall;
procedure processingInstruction(var strTarget: WideString
var strData: WideString)
safecall;
end;
NewSAXContentHandle = class(TInterfacedObject,IVBSAXContentHandler)
FMySAXContentHandle:MySAXContentHandle;
property ContentHandle: MySAXContentHandle read FMySAXContentHandle implements IVBSAXContentHandler;
end;
implementation
procedure MySAXContentHandle.startElement(var strNamespaceURI: WideString
var strLocalName: WideString;
var strQName: WideString
const oAttributes: IVBSAXAttributes)
safecall;
var i:integer;
s:WideString;
begin
s:='<' + strLocalName;
for i:=0 to oAttributes.length-1 do
begin
s:=s + ' '+ oAttributes.getLocalName(i)+'="'+oAttributes.getValue(i)+'"';
end;
s:=s+'>';
form1.memo1.lines.add(s);
end;
procedure MySAXContentHandle.endElement(var strNamespaceURI: WideString
var strLocalName: WideString;
var strQName: WideString)
safecall;
begin
form1.memo1.lines.add('</'+strLocalName+'>');
end;
procedure MySAXContentHandle.processingInstruction(var strTarget: WideString
var strData: WideString)
safecall;
begin
form1.memo1.lines.add('<?'+strTarget+' '+strData+'>');
end;
end.
编译通不过;很多 Undeclared identifier:
甚至连Invoke,GetIDsOfName,等都说没有;
关键再于在VB中 使用
Implements IVBSAXContentHandler
就可以对IVBSAXContentHandler的所有过程都重新实现一次;
在Delphi中不知道如何实现这个Implements?