VFP 愛用者社區 首頁 VFP 愛用者社區
本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入

用SAX實現xmltocursor (轉貼)

 
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區
上一篇主題 :: 下一篇主題  
發表人 內容
Ruey



註冊時間: 2003-03-12
文章: 1698
來自: tunglo

第 1 樓

發表發表於: 星期五 四月 02, 2004 11:50 pm    文章主題: 用SAX實現xmltocursor (轉貼) 引言回覆

來源:飛狐堂 boe
http://www.vfp.cn/blog/


用SAX實現xmltocursor

SAX:Simple API FOR XML 是和一個基於事件流的 XML 文檔解析方式,比 DOM 方式節省資源,速度快很多。
VFP 的 XMLTOCURSOR 採用 DOM 方式,對於稍大的文檔基本無法處理,筆者的一個 XML 文檔有 43 MB大小,內涵50000多條記錄,17個字段,用 VFP 8 sp1 的 xmltocursor 無法處理(等待20分鐘無果、且系統無法相應)。
利用 SAX 處理,可以做到4分多鐘解析出 cursor,(且可以支持進度條),系統資源佔用較小,沒有死機的感覺。雖說時間依然蠻長,但鑒於可以支持進度條,而且測試文件較大,所以這種基於 SAX的 XMLTOCURSOR 是可行的。

週末我會成文,與大家分享。

DOM 把 XML當作一棵樹看待,遇到大的 XML 要把這個樹生成,就需要很多資源、時間,慢是肯定的;當 XML 的規模較小的時候, DOM 的使用方便地優勢就很明顯。


employees.rar
---非緩衝模式
DEFINE CLASS XmlContentHandler AS custom
IMPLEMENTS IVBSAXContentHandler IN "c:\windows\system32\msxml4.dll"

DIMENSION aRecord[17]
iCol=-1
isData=.F.
isAfterStartElement=.F.
PROCEDURE Init()
CREATE CURSOR XMLTEMP(employeeid int NOT NULL,lastname c(20) NOT null,firstname c(10) NOT null,Title c(30) null,titleofcourtesy c(25) null,birthdate datetime null,hiredate datetime null,address c(60) null,city c(15) null,region c(15) null,postalcode c(10) null,country c(15) null,homephone c(24) null,extension c(4) null,note m null,reportsto i null,photopath m null)
SELECT XMLTEMP
SCATTER TO this.aRecord BLANK
ENDPROC

PROCEDURE IVBSAXContentHandler_documentLocator() AS VARIANT;
HELPSTRING "Receive an object for locating the origin of SAX document events."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_put_documentLocator( ISAXLocator) AS VARIANT;
HELPSTRING "Receive an object for locating the origin of SAX document events."
* add user code here
ENDPROC
PROCEDURE IVBSAXContentHandler_startDocument() AS VOID;
HELPSTRING "Receive notification of the beginning of a document."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_endDocument() AS VOID;
HELPSTRING "Receive notification of the end of a document."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_startPrefixMapping(strPrefix AS STRING @, strURI AS STRING @) AS VOID;
HELPSTRING "Begin the scope of a prefix-URI Namespace mapping."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_endPrefixMapping(strPrefix AS STRING @) AS VOID;
HELPSTRING "End the scope of a prefix-URI mapping."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_startElement(strNamespaceURI AS STRING @, strLocalName AS STRING @, strQName AS STRING @, oAttributes AS VARIANT) AS VOID;
HELPSTRING "Receive notification of the beginning of an element."
IF ALLTRIM(strLocalName)=='xml'
this.isData=.T.
this.iCol=-1
ENDIF
IF this.isData
this.iCol = this.iCol + 1
this.isAfterStartElement=.T.
ENDIF

ENDPROC

PROCEDURE IVBSAXContentHandler_endElement(strNamespaceURI AS STRING @, strLocalName AS STRING @, strQName AS STRING @) AS VOID;
HELPSTRING "Receive notification of the end of an element."
IF ALLTRIM(strLocalName)=='xml'
this.iCol=-1
SELECT XMLTEMP
APPEND FROM ARRAY this.aRecord
ENDIF
this.isAfterStartElement=.F.
ENDPROC

PROCEDURE IVBSAXContentHandler_characters(strChars AS STRING @) AS VOID;
HELPSTRING "Receive notification of character data."
IF this.iCol>0 AND this.isAfterStartElement
s=ALLTRIM(strChars)
DO CASE
CASE INLIST(this.iCol,1,16)
this.aRecord[this.iCol]=VAL(s)
CASE INLIST(this.iCol,6,7)
this.aRecord[this.iCol]=CTOT(s)
OTHERWISE
this.aRecord[this.iCol]=s
ENDCASE
ENDIF

ENDPROC

PROCEDURE IVBSAXContentHandler_ignorableWhitespace(strChars AS STRING @) AS VOID;
HELPSTRING "Receive notification of ignorable whitespace in element content."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_processingInstruction(strTarget AS STRING @, strData AS STRING @) AS VOID;
HELPSTRING "Receive notification of a processing instruction."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_skippedEntity(strName AS STRING @) AS VOID;
HELPSTRING "Receive notification of a skipped entity."
* add user code here
ENDPROC

ENDDEFINE
----
----50條記錄緩衝
DEFINE CLASS XmlContentHandler AS custom
IMPLEMENTS IVBSAXContentHandler IN "c:\windows\system32\msxml4.dll"

DIMENSION aRecord[50,17]
iCol=-1
isData=.F.
isAfterStartElement=.F.
iRow=0
PROCEDURE Init()
CREATE CURSOR XMLTEMP(employeeid int NOT NULL,lastname c(20) NOT null,firstname c(10) NOT null,Title c(30) null,titleofcourtesy c(25) null,birthdate datetime null,hiredate datetime null,address c(60) null,city c(15) null,region c(15) null,postalcode c(10) null,country c(15) null,homephone c(24) null,extension c(4) null,note m null,reportsto i null,photopath m null)
SELECT XMLTEMP
SCATTER TO this.aRecord BLANK
ENDPROC

PROCEDURE IVBSAXContentHandler_documentLocator() AS VARIANT;
HELPSTRING "Receive an object for locating the origin of SAX document events."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_put_documentLocator( ISAXLocator) AS VARIANT;
HELPSTRING "Receive an object for locating the origin of SAX document events."
* add user code here
ENDPROC
PROCEDURE IVBSAXContentHandler_startDocument() AS VOID;
HELPSTRING "Receive notification of the beginning of a document."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_endDocument() AS VOID;
HELPSTRING "Receive notification of the end of a document."
IF this.iRow>0
DIMENSION myRecord[this.iRow,17]
ACOPY(this.aRecord,myRecord,1,AELEMENT(this.aRecord,this.iRow,17))
SELECT XMLTEMP
APPEND FROM ARRAY myRecord
ENDIF
ENDPROC

PROCEDURE IVBSAXContentHandler_startPrefixMapping(strPrefix AS STRING @, strURI AS STRING @) AS VOID;
HELPSTRING "Begin the scope of a prefix-URI Namespace mapping."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_endPrefixMapping(strPrefix AS STRING @) AS VOID;
HELPSTRING "End the scope of a prefix-URI mapping."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_startElement(strNamespaceURI AS STRING @, strLocalName AS STRING @, strQName AS STRING @, oAttributes AS VARIANT) AS VOID;
HELPSTRING "Receive notification of the beginning of an element."
IF ALLTRIM(strLocalName)=='xml'
this.isData=.T.
this.iCol=-1
this.iRow = this.iRow + 1
ENDIF
IF this.isData
this.iCol = this.iCol + 1
this.isAfterStartElement=.T.
ENDIF

ENDPROC

PROCEDURE IVBSAXContentHandler_endElement(strNamespaceURI AS STRING @, strLocalName AS STRING @, strQName AS STRING @) AS VOID;
HELPSTRING "Receive notification of the end of an element."
IF ALLTRIM(strLocalName)=='xml'
this.iCol=-1
IF this.iRow=50
SELECT XMLTEMP
APPEND FROM ARRAY this.aRecord
this.iRow=0
ENDIF
ENDIF
this.isAfterStartElement=.F.
ENDPROC

PROCEDURE IVBSAXContentHandler_characters(strChars AS STRING @) AS VOID;
HELPSTRING "Receive notification of character data."
IF this.iCol>0 AND this.isAfterStartElement
s=ALLTRIM(strChars)
DO CASE
CASE INLIST(this.iCol,1,16)
this.aRecord[this.iRow,this.iCol]=VAL(s)
CASE INLIST(this.iCol,6,7)
this.aRecord[this.iRow,this.iCol]=CTOT(s)
OTHERWISE
this.aRecord[this.iRow,this.iCol]=s
ENDCASE
ENDIF

ENDPROC

PROCEDURE IVBSAXContentHandler_ignorableWhitespace(strChars AS STRING @) AS VOID;
HELPSTRING "Receive notification of ignorable whitespace in element content."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_processingInstruction(strTarget AS STRING @, strData AS STRING @) AS VOID;
HELPSTRING "Receive notification of a processing instruction."
* add user code here
ENDPROC

PROCEDURE IVBSAXContentHandler_skippedEntity(strName AS STRING @) AS VOID;
HELPSTRING "Receive notification of a skipped entity."
* add user code here
ENDPROC

ENDDEFINE

_________________
#############################
快樂媽咪系列幸福宅配,喝十全雞湯~原來幸福那麼簡單!!

學會VFP使用者社區的搜尋,Code才會更有趣~
#############################
回頂端
檢視會員個人資料 發送私人訊息
elleryq



註冊時間: 2007-06-21
文章: 768


第 2 樓

發表發表於: 星期二 四月 06, 2004 9:47 am    文章主題: 引言回覆

真是厲害啊~~
回頂端
檢視會員個人資料 發送私人訊息 參觀發表人的個人網站
syntech



註冊時間: 2003-05-16
文章: 4249
來自: Taipei,Taiwan

第 3 樓

發表發表於: 星期二 四月 06, 2004 10:27 am    文章主題: 引言回覆

引言回覆:

DOM 把 XML當作一棵樹看待,遇到大的 XML 要把這個樹生成,就需要很多資源、時間,慢是肯定的;當 XML 的規模較小的時候, DOM 的使用方便地優勢就很明顯。


這裡也提示了,如果可以分段處裡的話,DOM可是可以用的,
一直聽到 xmlTOcursor要耗不少資源,
心理也是怕怕的

_________________
如果公司有下列困擾:
1. 找不到便宜,快速,簡易的 生產排程軟體
2. 不知道如何快速排定 採購計劃
3. 成本抓不準,自己算比軟體算有用
4. 想學習系統規劃,想找系統架構的顧問

請聯絡我們,也許我們幫得上忙
回頂端
檢視會員個人資料 發送私人訊息 發送電子郵件 AIM Address
從之前的文章開始顯示:   
發表新主題   回覆主題    VFP 愛用者社區 首頁 -> VFP 討論區 所有的時間均為 台北時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
無法 在這個版面附加檔案
無法 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作