如果节点存在并在 Progress4GL 中检索值,如何检查 XML 文件
How to check XML file if node exists and retrieve value in Progress4GL
Progress4GL 开发人员您好,
在对 UPS 进行成功的 SOAP 调用后,我将以下 XML 响应存储在名为 cBody 的 longchar 变量中:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<trk:TrackResponse xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:trk="http://www.ups.com/XMLSchema/XOLTWS/Track/v2.0">
<common:Response xmlns:common="http://www.ups.com/XMLSchema/XOLTWS/Common/v1.0">
<common:ResponseStatus>
<common:Code>1</common:Code>
<common:Description>Success</common:Description>
</common:ResponseStatus>
<common:TransactionReference/>
</common:Response>
<trk:Shipment>
<trk:InquiryNumber>
<trk:Code>01</trk:Code>
<trk:Description>ShipmentIdentificationNumber</trk:Description>
<trk:Value>MYTRACKERNUMBER</trk:Value>
</trk:InquiryNumber>
...
我现在使用以下代码行将其存储为 X-DOCUMENT:
hDoc:LOAD("longchar",cBody2,FALSE).
现在我想检查我的回复是否有跟踪号,如果有我想将跟踪号存储为变量。看来这是可能的:
https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dvxml/examples-of-reading-an-input-xml-file.html
然而,这是我目前所拥有的,而且似乎没有用。没有输出但没有运行时错误:
....
hDoc:LOAD("longchar",cBody,FALSE).
DEFINE variable hNodeRef as HANDLE NO-UNDO.
CREATE X-NODEREF hNodeRef.
hDoc:GET-DOCUMENT-ELEMENT(hNodeRef).
IF hNodeRef:NAME = "trk:value" THEN
message hNoderef:GET-ATTRIBUTE("id") hNoderef:ATTRIBUTE-NAMES.
....
您需要沿着树走下去才能到达您想要的节点。像下面这样的东西。这很费力,您需要自己清理(如 finally 块)。
define variable hXmlDoc as handle no-undo.
define variable hXmlNode as handle no-undo.
define variable hXmlNode2 as handle no-undo.
define variable hXmlNode3 as handle no-undo.
define variable loop as integer no-undo.
define variable cnt as integer no-undo.
create x-document hXmlDoc.
hXmlDoc:load('file', 'soap.xml', no).
create x-noderef hXmlNode.
create x-noderef hXmlNode2.
create x-noderef hXmlNode3.
hXmlDoc:get-document-element(hXmlNode).
cnt = hXmlNode:num-children.
do loop = 1 to cnt:
hXmlNode:get-child(hXmlNode2, loop).
if hXmlNode2:name eq 'trk:Shipment' then
leave.
end.
cnt = hXmlNode2:num-children.
do loop = 1 to cnt:
hXmlNode2:get-child(hXmlNode3, loop).
if hXmlNode3:name eq 'trk:InquiryNumber' then
leave.
end.
// should be trk:InquiryNumber
cnt = hXmlNode3:num-children.
do loop = 1 to cnt:
hXmlNode3:get-child(hXmlNode, loop).
if hXmlNode:name eq 'trk:Value' then
leave.
end.
// should be trk:Value
hXmlNode:get-child(hXmlNode2, 1).
message
hXmlNode:name skip
hXmlNode2:node-value
view-as alert-box.
finally:
delete object hXmlNode.
delete object hXmlNode2.
delete object hXmlNode3.
delete object hXmlDoc.
end finally.
虽然 Peter 的回答没有错,但使用自动 XML 到 DataSet 映射的功能可以简单得多。在这种情况下,您甚至不需要将数据集静态建模为 XML,ABL 会自动为您完成:
def var lcresponse as longchar initial '<?xml version="1.0" encoding="ISO-8859-1" ?>
<trk:TrackResponse xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:trk="http://www.ups.com/XMLSchema/XOLTWS/Track/v2.0">
<common:Response xmlns:common="http://www.ups.com/XMLSchema/XOLTWS/Common/v1.0">
<common:ResponseStatus>
<common:Code>1</common:Code>
<common:Description>Success</common:Description>
</common:ResponseStatus>
<common:TransactionReference/>
</common:Response>
<trk:Shipment>
<trk:InquiryNumber>
<trk:Code>01</trk:Code>
<trk:Description>ShipmentIdentificationNumber</trk:Description>
<trk:Value>MYTRACKERNUMBER</trk:Value>
</trk:InquiryNumber>
</trk:Shipment>
</trk:TrackResponse>'.
def var hds as handle no-undo.
def var hb as handle no-undo.
create dataset hds.
hds:read-xml( "longchar", lcresponse, ?, ?, ? ).
hb = hds:get-buffer-handle("InquiryNumber").
hb:find-unique() no-error.
if hb:available then
message hb:buffer-field("Value"):buffer-value.
https://abldojo.services.progress.com:443/#/?shareId=5ed946344b1a0f40c34b8c5a
Progress4GL 开发人员您好,
在对 UPS 进行成功的 SOAP 调用后,我将以下 XML 响应存储在名为 cBody 的 longchar 变量中:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<trk:TrackResponse xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:trk="http://www.ups.com/XMLSchema/XOLTWS/Track/v2.0">
<common:Response xmlns:common="http://www.ups.com/XMLSchema/XOLTWS/Common/v1.0">
<common:ResponseStatus>
<common:Code>1</common:Code>
<common:Description>Success</common:Description>
</common:ResponseStatus>
<common:TransactionReference/>
</common:Response>
<trk:Shipment>
<trk:InquiryNumber>
<trk:Code>01</trk:Code>
<trk:Description>ShipmentIdentificationNumber</trk:Description>
<trk:Value>MYTRACKERNUMBER</trk:Value>
</trk:InquiryNumber>
...
我现在使用以下代码行将其存储为 X-DOCUMENT:
hDoc:LOAD("longchar",cBody2,FALSE).
现在我想检查我的回复是否有跟踪号,如果有我想将跟踪号存储为变量。看来这是可能的: https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dvxml/examples-of-reading-an-input-xml-file.html
然而,这是我目前所拥有的,而且似乎没有用。没有输出但没有运行时错误:
....
hDoc:LOAD("longchar",cBody,FALSE).
DEFINE variable hNodeRef as HANDLE NO-UNDO.
CREATE X-NODEREF hNodeRef.
hDoc:GET-DOCUMENT-ELEMENT(hNodeRef).
IF hNodeRef:NAME = "trk:value" THEN
message hNoderef:GET-ATTRIBUTE("id") hNoderef:ATTRIBUTE-NAMES.
....
您需要沿着树走下去才能到达您想要的节点。像下面这样的东西。这很费力,您需要自己清理(如 finally 块)。
define variable hXmlDoc as handle no-undo.
define variable hXmlNode as handle no-undo.
define variable hXmlNode2 as handle no-undo.
define variable hXmlNode3 as handle no-undo.
define variable loop as integer no-undo.
define variable cnt as integer no-undo.
create x-document hXmlDoc.
hXmlDoc:load('file', 'soap.xml', no).
create x-noderef hXmlNode.
create x-noderef hXmlNode2.
create x-noderef hXmlNode3.
hXmlDoc:get-document-element(hXmlNode).
cnt = hXmlNode:num-children.
do loop = 1 to cnt:
hXmlNode:get-child(hXmlNode2, loop).
if hXmlNode2:name eq 'trk:Shipment' then
leave.
end.
cnt = hXmlNode2:num-children.
do loop = 1 to cnt:
hXmlNode2:get-child(hXmlNode3, loop).
if hXmlNode3:name eq 'trk:InquiryNumber' then
leave.
end.
// should be trk:InquiryNumber
cnt = hXmlNode3:num-children.
do loop = 1 to cnt:
hXmlNode3:get-child(hXmlNode, loop).
if hXmlNode:name eq 'trk:Value' then
leave.
end.
// should be trk:Value
hXmlNode:get-child(hXmlNode2, 1).
message
hXmlNode:name skip
hXmlNode2:node-value
view-as alert-box.
finally:
delete object hXmlNode.
delete object hXmlNode2.
delete object hXmlNode3.
delete object hXmlDoc.
end finally.
虽然 Peter 的回答没有错,但使用自动 XML 到 DataSet 映射的功能可以简单得多。在这种情况下,您甚至不需要将数据集静态建模为 XML,ABL 会自动为您完成:
def var lcresponse as longchar initial '<?xml version="1.0" encoding="ISO-8859-1" ?>
<trk:TrackResponse xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:trk="http://www.ups.com/XMLSchema/XOLTWS/Track/v2.0">
<common:Response xmlns:common="http://www.ups.com/XMLSchema/XOLTWS/Common/v1.0">
<common:ResponseStatus>
<common:Code>1</common:Code>
<common:Description>Success</common:Description>
</common:ResponseStatus>
<common:TransactionReference/>
</common:Response>
<trk:Shipment>
<trk:InquiryNumber>
<trk:Code>01</trk:Code>
<trk:Description>ShipmentIdentificationNumber</trk:Description>
<trk:Value>MYTRACKERNUMBER</trk:Value>
</trk:InquiryNumber>
</trk:Shipment>
</trk:TrackResponse>'.
def var hds as handle no-undo.
def var hb as handle no-undo.
create dataset hds.
hds:read-xml( "longchar", lcresponse, ?, ?, ? ).
hb = hds:get-buffer-handle("InquiryNumber").
hb:find-unique() no-error.
if hb:available then
message hb:buffer-field("Value"):buffer-value.
https://abldojo.services.progress.com:443/#/?shareId=5ed946344b1a0f40c34b8c5a