如何使用 Progress 4GL 读取 XML 文件并导出项目
How to read a XML file and export an item using Progress 4GL
当我执行以下代码来读取一个 XML 文件时,我只需要那个 XML 文件中的 3 个项目,但是这段代码无法读取它。
密码是:
DEFINE VARIABLE hDoc AS HANDLE NO-UNDO.
DEFINE VARIABLE hRoot AS HANDLE NO-UNDO.
DEFINE VARIABLE hTable AS HANDLE NO-UNDO.
DEFINE VARIABLE hField AS HANDLE NO-UNDO.
DEFINE VARIABLE hText AS HANDLE NO-UNDO.
DEFINE VARIABLE hBuf AS HANDLE NO-UNDO.
DEFINE VARIABLE hDBFld AS HANDLE NO-UNDO.
DEFINE VARIABLE ix AS INTEGER NO-UNDO.
DEFINE VARIABLE jx AS INTEGER NO-UNDO.
DEFINE VARIABLE returnCode AS DECIMAL NO-UNDO.
DEFINE VARIABLE returnMessage AS CHARACTER NO-UNDO.
DEFINE VARIABLE bravoId AS CHAR NO-UNDO.
CREATE X-DOCUMENT hDoc.
CREATE X-NODEREF hRoot.
CREATE X-NODEREF hTable.
CREATE X-NODEREF hField.
CREATE X-NODEREF hText.
/* Read in the file created in i-outcus.p */
hDoc:LOAD("file", "C:\user53.xml", TRUE).
hDoc:GET-DOCUMENT-ELEMENT(hRoot).
REPEAT ix = 1 TO hRoot:NUM-CHILDREN:
hRoot:GET-CHILD(hTable, ix).
/* Get the fields given as attributes */
string(returnCode) = hTable:GET-NODE("returnCode").
returnMessage = hTable:GET-NODE("returnMessage").
bravoId = hTable:GET-NODE("Id").
REPEAT jx = 1 TO hTable:NUM-CHILDREN:
hTable:GET-CHILD(hField, jx).
hField:GET-CHILD(hText, 1).
hDBFld:BUFFER-VALUE = hTEXT:NODE-VALUE.
END.
END.
DELETE OBJECT hDoc.
DELETE OBJECT hRoot.
DELETE OBJECT hTable.
DELETE OBJECT hField.
DELETE OBJECT hText.
FOR EACH v:
DISPLAY ' ReturnCode: ' + STRING(returnCode) + ' - ReturnMessage: ' + returnMessage + ' id: ' + id.
END.
XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns1:ImportProfilesResponse xmlns:ns1="http://host.bs.com/common/webservice/ProfileManagement/">
<returnCode>-996</returnCode>
<returnMessage>Invalid SOAP Request Object - 112(FISCAL_CODE);</returnMessage>
<id>0000</id>
</ns1:ImportProfilesResponse>
</soapenv:Body>
</soapenv:Envelope>
有多种方法可以做到这一点。也许您可以定义一个带有临时表的数据集,然后简单地将数据读入其中。
保留部分解决方案,这就是我最终得到的结果。它也可以递归地完成(遍历 xml)。
基本上你需要做的是遍历[=17=],当你找到正确的节点时,你再降一级等等。你还需要了解节点的值实际上是一个节点本身。
DEFINE VARIABLE hDoc AS HANDLE NO-UNDO.
DEFINE VARIABLE hRoot AS HANDLE NO-UNDO.
DEFINE VARIABLE hTable AS HANDLE NO-UNDO.
DEFINE VARIABLE hField AS HANDLE NO-UNDO.
DEFINE VARIABLE hText AS HANDLE NO-UNDO.
DEFINE VARIABLE hValue AS HANDLE NO-UNDO.
DEFINE VARIABLE ix AS INTEGER NO-UNDO.
DEFINE VARIABLE jx AS INTEGER NO-UNDO.
DEFINE VARIABLE kx AS INTEGER NO-UNDO.
DEFINE VARIABLE returnCode AS DECIMAL NO-UNDO.
DEFINE VARIABLE returnMessage AS CHARACTER NO-UNDO.
DEFINE VARIABLE bravoId AS CHAR NO-UNDO.
CREATE X-DOCUMENT hDoc.
CREATE X-NODEREF hRoot.
CREATE X-NODEREF hTable.
CREATE X-NODEREF hField.
CREATE X-NODEREF hText.
CREATE X-NODEREF hValue.
/* Read in the file created in i-outcus.p */
hDoc:LOAD("file", "C:\temp\user53.xml", FALSE).
hDoc:GET-DOCUMENT-ELEMENT(hRoot).
REPEAT ix = 1 TO hRoot:NUM-CHILDREN:
hRoot:GET-CHILD(hTable, ix).
IF hTable:NAME = "soapEnv:body" THEN DO:
REPEAT jx = 1 TO hTable:NUM-CHILDREN:
hTable:GET-CHILD(hField, jx).
IF hField:NAME = "ns1:ImportProfilesResponse" THEN DO:
REPEAT kx = 1 TO hFIeld:NUM-CHILDREN:
hField:GET-CHILD(hText, kx).
IF hText:NUM-CHILDREN = 1 THEN DO:
hText:GET-CHILD(hValue, 1).
IF hText:NAME = "returnCode" THEN DO:
returnCode = DECIMAL(hValue:NODE-VALUE) NO-ERROR.
END.
ELSE IF hText:NAME = "returnMessage" THEN DO:
returnMessage = hValue:NODE-VALUE.
END.
ELSE IF hText:NAME = "id" THEN DO:
bravoId = hValue:NODE-VALUE.
END.
END.
END.
END.
END.
END.
END.
DELETE OBJECT hDoc.
DELETE OBJECT hRoot.
DELETE OBJECT hTable.
DELETE OBJECT hField.
DELETE OBJECT hText.
DELETE OBJECT hValue.
MESSAGE ' ReturnCode: ' STRING(returnCode) SKIP
' ReturnMessage: ' returnMessage SKIP
' Id: ' bravoId VIEW-AS ALERT-BOX .
为了阅读和处理 XML 的几个片段,我认为您最好使用 SAX reader。
这个 对如何实现它有一些想法。
根据我的经验,SAX reader 比完整的 XML 文档更容易使用。
当我执行以下代码来读取一个 XML 文件时,我只需要那个 XML 文件中的 3 个项目,但是这段代码无法读取它。
密码是:
DEFINE VARIABLE hDoc AS HANDLE NO-UNDO.
DEFINE VARIABLE hRoot AS HANDLE NO-UNDO.
DEFINE VARIABLE hTable AS HANDLE NO-UNDO.
DEFINE VARIABLE hField AS HANDLE NO-UNDO.
DEFINE VARIABLE hText AS HANDLE NO-UNDO.
DEFINE VARIABLE hBuf AS HANDLE NO-UNDO.
DEFINE VARIABLE hDBFld AS HANDLE NO-UNDO.
DEFINE VARIABLE ix AS INTEGER NO-UNDO.
DEFINE VARIABLE jx AS INTEGER NO-UNDO.
DEFINE VARIABLE returnCode AS DECIMAL NO-UNDO.
DEFINE VARIABLE returnMessage AS CHARACTER NO-UNDO.
DEFINE VARIABLE bravoId AS CHAR NO-UNDO.
CREATE X-DOCUMENT hDoc.
CREATE X-NODEREF hRoot.
CREATE X-NODEREF hTable.
CREATE X-NODEREF hField.
CREATE X-NODEREF hText.
/* Read in the file created in i-outcus.p */
hDoc:LOAD("file", "C:\user53.xml", TRUE).
hDoc:GET-DOCUMENT-ELEMENT(hRoot).
REPEAT ix = 1 TO hRoot:NUM-CHILDREN:
hRoot:GET-CHILD(hTable, ix).
/* Get the fields given as attributes */
string(returnCode) = hTable:GET-NODE("returnCode").
returnMessage = hTable:GET-NODE("returnMessage").
bravoId = hTable:GET-NODE("Id").
REPEAT jx = 1 TO hTable:NUM-CHILDREN:
hTable:GET-CHILD(hField, jx).
hField:GET-CHILD(hText, 1).
hDBFld:BUFFER-VALUE = hTEXT:NODE-VALUE.
END.
END.
DELETE OBJECT hDoc.
DELETE OBJECT hRoot.
DELETE OBJECT hTable.
DELETE OBJECT hField.
DELETE OBJECT hText.
FOR EACH v:
DISPLAY ' ReturnCode: ' + STRING(returnCode) + ' - ReturnMessage: ' + returnMessage + ' id: ' + id.
END.
XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns1:ImportProfilesResponse xmlns:ns1="http://host.bs.com/common/webservice/ProfileManagement/">
<returnCode>-996</returnCode>
<returnMessage>Invalid SOAP Request Object - 112(FISCAL_CODE);</returnMessage>
<id>0000</id>
</ns1:ImportProfilesResponse>
</soapenv:Body>
</soapenv:Envelope>
有多种方法可以做到这一点。也许您可以定义一个带有临时表的数据集,然后简单地将数据读入其中。
保留部分解决方案,这就是我最终得到的结果。它也可以递归地完成(遍历 xml)。
基本上你需要做的是遍历[=17=],当你找到正确的节点时,你再降一级等等。你还需要了解节点的值实际上是一个节点本身。
DEFINE VARIABLE hDoc AS HANDLE NO-UNDO.
DEFINE VARIABLE hRoot AS HANDLE NO-UNDO.
DEFINE VARIABLE hTable AS HANDLE NO-UNDO.
DEFINE VARIABLE hField AS HANDLE NO-UNDO.
DEFINE VARIABLE hText AS HANDLE NO-UNDO.
DEFINE VARIABLE hValue AS HANDLE NO-UNDO.
DEFINE VARIABLE ix AS INTEGER NO-UNDO.
DEFINE VARIABLE jx AS INTEGER NO-UNDO.
DEFINE VARIABLE kx AS INTEGER NO-UNDO.
DEFINE VARIABLE returnCode AS DECIMAL NO-UNDO.
DEFINE VARIABLE returnMessage AS CHARACTER NO-UNDO.
DEFINE VARIABLE bravoId AS CHAR NO-UNDO.
CREATE X-DOCUMENT hDoc.
CREATE X-NODEREF hRoot.
CREATE X-NODEREF hTable.
CREATE X-NODEREF hField.
CREATE X-NODEREF hText.
CREATE X-NODEREF hValue.
/* Read in the file created in i-outcus.p */
hDoc:LOAD("file", "C:\temp\user53.xml", FALSE).
hDoc:GET-DOCUMENT-ELEMENT(hRoot).
REPEAT ix = 1 TO hRoot:NUM-CHILDREN:
hRoot:GET-CHILD(hTable, ix).
IF hTable:NAME = "soapEnv:body" THEN DO:
REPEAT jx = 1 TO hTable:NUM-CHILDREN:
hTable:GET-CHILD(hField, jx).
IF hField:NAME = "ns1:ImportProfilesResponse" THEN DO:
REPEAT kx = 1 TO hFIeld:NUM-CHILDREN:
hField:GET-CHILD(hText, kx).
IF hText:NUM-CHILDREN = 1 THEN DO:
hText:GET-CHILD(hValue, 1).
IF hText:NAME = "returnCode" THEN DO:
returnCode = DECIMAL(hValue:NODE-VALUE) NO-ERROR.
END.
ELSE IF hText:NAME = "returnMessage" THEN DO:
returnMessage = hValue:NODE-VALUE.
END.
ELSE IF hText:NAME = "id" THEN DO:
bravoId = hValue:NODE-VALUE.
END.
END.
END.
END.
END.
END.
END.
DELETE OBJECT hDoc.
DELETE OBJECT hRoot.
DELETE OBJECT hTable.
DELETE OBJECT hField.
DELETE OBJECT hText.
DELETE OBJECT hValue.
MESSAGE ' ReturnCode: ' STRING(returnCode) SKIP
' ReturnMessage: ' returnMessage SKIP
' Id: ' bravoId VIEW-AS ALERT-BOX .
为了阅读和处理 XML 的几个片段,我认为您最好使用 SAX reader。
这个
根据我的经验,SAX reader 比完整的 XML 文档更容易使用。