【问题标题】:Progress 4GL: Reading from XML to DatasetProgress 4GL:从 XML 读取数据集
【发布时间】:2014-08-20 19:49:07
【问题描述】:

当我尝试使用 Dataset 和 READ-XML 方法从 XML 读取到 TempTables 时,它可以正常工作。 但问题是这样的:如果标签中有属性,那么它返回空结果而不是元素值。尝试了不同的方法,但没有得到任何结果。

我发现它只有在属性名称是“xmlns”时才有效,就像在这种情况下Reading XML file to Dataset in Progress-4gl

这是我的代码和 XML。

<?xml version="1.0" encoding="ISO-8859-15"?>
<?xml-stylesheet type="text/xsl" href="Test.xsl"?>
<ReceiverInfo Version="2.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Test.xsd">
   <MessageDetails>
      <MessageTypeCode Axmlns="">RECEIVERINFO</MessageTypeCode>
   </MessageDetails>
   <MessageDetails>
      <MessageTypeCode Axmlns="">RECEIVERINFO2</MessageTypeCode>
   </MessageDetails>
</ReceiverInfo>

和代码:

def var icount as int no-undo initial 0.

DEF TEMP-TABLE ReceiverInfo NO-UNDO
   FIELD foo AS LOG.

DEF TEMP-TABLE MessageDetails NO-UNDO
   FIELD MessageTypeCode as CHAR XML-NODE-TYPE "Element".

DEF DATASET data FOR ReceiverInfo, MessageDetails.

DATASET data:READ-XML("file", "/home/ars/temp/tofile.xml", "empty", ?, FALSE, ?, "IGNORE") NO-ERROR.

DO icount = 1 TO ERROR-STATUS:NUM-MESSAGES:
      DISP ERROR-STATUS:GET-MESSAGE(icount) format "x(50)".
END.

FOR EACH MessageDetails.
      DISP MessageDetails.MessageTypeCode format "x(40)".
END.

感谢您的帮助!

【问题讨论】:

  • 我想知道您的 XML 是否已损坏。 Axmlns="" 部分真的应该类似于 xmlns:something="" 吗? xmlns 是“xml 命名空间前缀”。从您的代码中删除 Axlmns="" ,它基本上可以工作。
  • 是的,我知道如果我删除该属性,它会起作用。例如,Axmlns 就在那里,对于真实数据,它可能类似于 MessageType="type"。问题是当属性存在时我无法获得任何值/

标签: xml progress-4gl openedge


【解决方案1】:

由于属性是 MessageTypeCode 的子属性,因此 MessageTypeCode 应该是临时表而不是字段。 ReceiverInfo 可以是数据集。 我更喜欢使用 PARENT-ID-RELATION 来链接父 (MessageDetails) 和子 (MessageTypeCode) 临时表。

DEFINE TEMP-TABLE MessageDetails NO-UNDO
    FIELD foo AS LOGICAL.

DEFINE TEMP-TABLE MessageTypeCode NO-UNDO
    FIELD Axmlns               AS CHARACTER XML-NODE-TYPE "Attribute"
    FIELD ElementValue         AS CHARACTER XML-NODE-TYPE "Text"
    FIELD MessageDetails_recid AS RECID     XML-NODE-TYPE "Hidden".

DEFINE DATASET ReceiverInfo
      FOR MessageDetails, MessageTypeCode
      PARENT-ID-RELATION tab1tab2 FOR MessageDetails, MessageTypeCode PARENT-ID-FIELD MessageDetails_recid.

DATASET ReceiverInfo:READ-XML("file", "/home/ars/temp/tofile.xml", "empty", ?, FALSE, ?, "IGNORE") NO-ERROR.

FOR EACH MessageTypeCode:
    DISP MessageTypeCode.ElementValue FORMAT "X(30)"
         MessageTypeCode.Axmlns      
         MessageTypeCode.MessageDetails_recid.
END.

您可以使用 XML-NODE-TYPE "Text" 来获取 MessageTypeCode 的值。

注意:每个表格只能包含一个 TEXT 字段。当表包含 TEXT 字段时,不能包含 ELEMENT 字段;它只能包含 ATTRIBUTE 字段。包含 TEXT 字段的表不能是嵌套数据关系的一部分。

【讨论】:

  • 不错的答案!您可以/应该将“SERIALIZE-HIDDEN”或 XML-NODE-TYPE“HIDDEN”添加到“foo”字段,以将其标记为隐藏。在这种情况下没有任何区别,但如果您也决定“WRITE-XML”,可能会这样做。
  • 我完全同意 Jensd。刚刚忘记了:)
  • 谢谢!我有 10.2B 版本并且没有 PARENT-ID-RELATION 功能,但我以同样的方式做到了 - 一个标签的一个临时表,它可以工作。之前尝试过,但不是节点类型“文本”而是使用节点类型“元素”。谢谢,它有效! :)
  • 有没有办法在 10.2B 版本中使用多个相同的标签来做到这一点。
【解决方案2】:

要在以下版本 10.x 中执行此操作:

DEFINE TEMP-TABLE MessageDetails NO-UNDO XML-NODE-NAME "MessageDetails" FIELD c_recid AS RECID XML-NODE-TYPE “隐藏”。 DEFINE TEMP-TABLE MessageTypeCode NO-UNDO 字段 Axmlns 作为字符 XML-NODE-TYPE “属性” 字段元素值作为字符 XML 节点类型“文本” FIELD c_recid AS RECID XML-NODE-TYPE “隐藏”。 定义数据集 dsReceiverInfo XML-NODE-NAME 'ReceiverInfo' FOR MessageDetails, MessageTypeCode 数据关系 dr1 用于 MessageDetails,MessageTypeCode 关系字段(c_recid,c_recid)嵌套外键隐藏。 数据集 dsReceiverInfo:READ-XML("file", "/home/ars/temp/tofile.xml", "empty", ?, FALSE, ?, "IGNORE")。 对于每个 MessageTypeCode: DISP MessageTypeCode.c_recid MessageTypeCode.Axmlns MessageTypeCode.ElementValue 格式“X(20)” 使用 STREAM-IO 宽度 300。 结尾。

【讨论】:

    猜你喜欢
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-01
    • 2019-01-28
    • 2019-01-16
    • 1970-01-01
    • 2014-12-07
    相关资源
    最近更新 更多