如何使用Progress 4GL解析XML?

时间:2018-12-31 16:46:36

标签: openedge progress-4gl

See original XML

比较上一行后,我需要解析XML。请看附件图片

下面是我用于解析XML的进度4GL查询

DEFINE INPUT PARAMETER ipc_fileName AS CHARACTER.

DEFINE VARIABLE cSegmentName AS CHARACTER   NO-UNDO.
DEFINE VARIABLE i AS INTEGER NO-UNDO.
DEFINE VARIABLE i661 AS INTEGER NO-UNDO.
DEFINE VARIABLE cInputData AS CHARACTER NO-UNDO.
DEFINE VARIABLE lv_c_Customer_Number AS INTEGER NO-UNDO.

INPUT FROM VALUE(ipc_FileName).
 IF cInputData = "" THEN NEXT.
    cSegmenTNAME = SUBSTRING(cInputData,1,3).     

CASE cSegmenTNAME :
        WHEN "661" THEN DO:
                 i = i + 1.
            IF LENGTH(cInputData) = 128 THEN DO:
                ASSIGN
                i661                 = i
                lv_c_Customer_Number = SUBSTRING(cInputData,6,9).
END.

就像明智的话,我可以解析每一行,但我的疑问是,如果前一行以664开头,该如何解析663行。

这里有任何答案。

1 个答案:

答案 0 :(得分:0)

要解析“进行中的XML”,您有几种选择。您的示例中均未使用这两个。

选项:

DATASET和TEMP-TABLES可以读取(格式正确的)XML。

代表XML的DATASET几乎可以读取任何XML。对于简单的XML,这可能非常容易。临时表可以直接读取xml(如果该xml与临时表的表示匹配)。除非xml实际上是序列化的临时表,否则通常不是这种情况。

将xml读入数据集和临时表需要对数据集和临时表有相当的了解,以及如何格式化它们并使用“ serialize-name”,“ serialize-hidden”等属性对其进行改编。

来自https://knowledgebase.progress.com/articles/Article/How-to-read-an-XML-in-a-temp-table-using-READ-XML的示例:

DEFINE VARIABLE lcc AS LONGCHAR INIT "<A><B>Red</B><B>Green</B></A>". 

DEFINE TEMP-TABLE ttb SERIALIZE-NAME "B" 
    FIELD cc AS CHAR XML-NODE-TYPE "text". 

DEFINE DATASET dsa SERIALIZE-NAME "A" FOR ttb. 

DATASET dsa:READ-XML( "longchar", lcc, ?, ?, ? ). 

FOR EACH ttb: 
    MESSAGE ttb.cc VIEW-AS ALERT-BOX. 
END.

文档对象模型(X-DOCUMENT)

使用DOM创建一个X-DOCUMENT对象,它可以读取xml。然后,您将具有一个包含XML数据的树结构。您将不得不自己分析,以便准备走动节点之树...

示例(从https://knowledgebase.progress.com/articles/Article/P21055复制):

  

下面的代码读取一个名为personal.xml的文件,处理其所有子节点,并在节点名称为“ person”的情况下显示信息:

/* e-attnam.p */
DEFINE VARIABLE hDoc AS HANDLE NO-UNDO.
DEFINE VARIABLE hRoot AS HANDLE NO-UNDO.
DEFINE VARIABLE good AS LOGICAL NO-UNDO.

CREATE X-DOCUMENT hDoc.
CREATE X-NODEREF hRoot.

hDoc:LOAD("file","personal.xml",TRUE).

hDoc:GET-DOCUMENT-ELEMENT(hRoot).

RUN GetChildren(hRoot, 1).

DELETE OBJECT hDoc.
DELETE OBJECT hRoot.

PROCEDURE GetChildren:
DEFINE INPUT PARAMETER hParent AS HANDLE NO-UNDO.
DEFINE INPUT PARAMETER level AS INTEGER NO-UNDO.

DEFINE VARIABLE i AS INTEGER NO-UNDO.
DEFINE VARIABLE hNoderef AS HANDLE NO-UNDO.

CREATE X-NODEREF hNoderef.

REPEAT i = 1 TO hParent:NUM-CHILDREN:
   good = hParent:GET-CHILD(hNoderef,i).
   IF NOT good THEN
LEAVE.
   IF hNoderef:SUBTYPE <> "element" THEN
NEXT.
   IF hNoderef:NAME = "person" THEN
       MESSAGE "getattr id gives" hNoderef:GET-ATTRIBUTE("id") hNoderef:ATTRIBUTE-NAMES.
   RUN GetChildren(hNoderef, (level + 1)).
END.

DELETE OBJECT hNoderef.
END PROCEDURE.

用于XML(SAX)的简单API

这也许是一种更轻量级的XML方法。您将必须编写代码来“响应” XML中某些节点的存在。

可以在https://knowledgebase.progress.com/articles/Article/000035469

找到示例

关于XML和Progress的所有内容:https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dvxml%2Fpreface.html%23