如何使用Progress 4GL语言解析XML文件?

问题描述 投票:-2回答:1

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行。

任何答案在这里赞赏。

openedge progress-4gl
1个回答
0
投票

要解析XML in Progress,您有几个选项。在您的示例中都没有使用这些。

选项:

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

几乎所有XML都可以由代表XML的DATASET读取。对于简单的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 API(SAX)

这可能是一种更轻量级的XML方法。您将不得不编写“反应”XML中某些节点存在的代码。

例子可以在https://knowledgebase.progress.com/articles/Article/000035469找到

对于所有XML和进展:https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dvxml%2Fpreface.html%23

© www.soinside.com 2019 - 2024. All rights reserved.