借助第三方XSD生成ProDataSet并映射异构库数据生成XML的问题咨询
Progress ProDataSet 动态映射异构数据生成符合XSD的XML解决方案
1. 实现思路可行性
该思路完全可行。你遇到的子记录丢失问题,核心原因是临时表未与ProDataSet的父子关联规则匹配,且填充数据时未正确维护父子记录的关联键值。只要确保临时表结构、关联关系与ProDataSet从XSD读取的定义完全对齐,同时在数据映射阶段正确传递关联字段值,就能解决问题。
2. 完整实现示例
以下是基于ABL的完整实现代码,包含XSD读取、临时表创建、异构数据映射、ProDataSet关联及XML生成的全流程:
DEFINE VARIABLE hProDataSet AS HANDLE NO-UNDO. DEFINE VARIABLE cXsdPath AS CHARACTER NO-UNDO INITIAL "C:\third-party-schema.xsd". DEFINE VARIABLE cXmlOutputPath AS CHARACTER NO-UNDO INITIAL "C:\output.xml". /* 1. 读取第三方XSD生成动态ProDataSet */ CREATE PRO-DATASET hProDataSet. hProDataSet:READ-XMLSCHEMA(FILE, cXsdPath, ?, ?, ?, TRUE). /* 2. 动态创建匹配ProDataSet结构的临时表,并建立关联 */ DEFINE VARIABLE i AS INTEGER NO-UNDO. DO i = 1 TO hProDataSet:NUM-BUFFERS: DEFINE VARIABLE hDsBuffer AS HANDLE NO-UNDO. DEFINE VARIABLE hTempTable AS HANDLE NO-UNDO. hDsBuffer = hProDataSet:GET-BUFFER-HANDLE(i). /* 创建与ProDataSet表结构一致的临时表 */ CREATE TEMP-TABLE hTempTable LIKE hDsBuffer:BUFFER-FIELD. hTempTable:TEMP-TABLE-PREPARE(hDsBuffer:NAME). /* 为子表建立与父表的外键关联(匹配XSD定义的父子关系) */ DEFINE VARIABLE j AS INTEGER NO-UNDO. DO j = 1 TO hProDataSet:NUM-RELATIONS: DEFINE VARIABLE hRelation AS HANDLE NO-UNDO. hRelation = hProDataSet:GET-RELATION-HANDLE(j). IF hRelation:CHILD-BUFFER = hDsBuffer THEN hTempTable:ADD-FOREIGN-KEY( hRelation:CHILD-FIELDS, hTempTable:NAME, hRelation:PARENT-BUFFER:NAME, hRelation:PARENT-FIELDS, "CASCADE", "CASCADE" ). END. END. /* 3. 从异构数据库读取数据,映射填充到临时表(示例逻辑,需替换为你的实际数据源查询) */ /* 示例:处理父表数据 */ DEFINE VARIABLE hParentTempBuffer AS HANDLE NO-UNDO. hParentTempBuffer = TEMP-TABLE-HANDLE("ParentTableFromXSD"):DEFAULT-BUFFER-HANDLE. CREATE QUERY hParentQuery. hParentQuery:ADD-BUFFER(hParentTempBuffer). /* 替换为你的异构库父表查询语句 */ hParentQuery:QUERY-PREPARE("FOR EACH YourHeteroDB.ParentTable"). hParentQuery:QUERY-OPEN(). hParentQuery:GET-FIRST(). DO WHILE hParentQuery:QUERY-OFF-EQUAL = FALSE: /* 创建临时表父记录,字段映射 */ hParentTempBuffer:BUFFER-CREATE(). hParentTempBuffer:BUFFER-FIELD("XSD_Parent_ID"):BUFFER-VALUE = YourHeteroDB.ParentTable.DB_Parent_ID. hParentTempBuffer:BUFFER-FIELD("XSD_Parent_Name"):BUFFER-VALUE = YourHeteroDB.ParentTable.DB_Parent_Name. /* 其他字段映射... */ /* 处理对应子表数据 */ DEFINE VARIABLE hChildTempBuffer AS HANDLE NO-UNDO. hChildTempBuffer = TEMP-TABLE-HANDLE("ChildTableFromXSD"):DEFAULT-BUFFER-HANDLE. CREATE QUERY hChildQuery. hChildQuery:ADD-BUFFER(hChildTempBuffer). /* 替换为你的异构库子表查询语句,注意关联父键 */ hChildQuery:QUERY-PREPARE("FOR EACH YourHeteroDB.ChildTable WHERE DB_Parent_ID = " + STRING(YourHeteroDB.ParentTable.DB_Parent_ID)). hChildQuery:QUERY-OPEN(). hChildQuery:GET-FIRST(). DO WHILE hChildQuery:QUERY-OFF-EQUAL = FALSE: /* 创建临时表子记录,字段映射+维护父键关联 */ hChildTempBuffer:BUFFER-CREATE(). hChildTempBuffer:BUFFER-FIELD("XSD_Child_ID"):BUFFER-VALUE = YourHeteroDB.ChildTable.DB_Child_ID. hChildTempBuffer:BUFFER-FIELD("XSD_Parent_ID"):BUFFER-VALUE = YourHeteroDB.ParentTable.DB_Parent_ID. hChildTempBuffer:BUFFER-FIELD("XSD_Child_Value"):BUFFER-VALUE = YourHeteroDB.ChildTable.DB_Child_Value. /* 其他字段映射... */ hChildQuery:GET-NEXT(). END. hChildQuery:QUERY-CLOSE(). DELETE OBJECT hChildQuery. hParentQuery:GET-NEXT(). END. hParentQuery:QUERY-CLOSE(). DELETE OBJECT hParentQuery. /* 4. 将临时表关联到ProDataSet,生成符合XSD的XML */ DO i = 1 TO hProDataSet:NUM-BUFFERS: DEFINE VARIABLE hDsBuffer AS HANDLE NO-UNDO. DEFINE VARIABLE hTempBuffer AS HANDLE NO-UNDO. hDsBuffer = hProDataSet:GET-BUFFER-HANDLE(i). hTempBuffer = TEMP-TABLE-HANDLE(hDsBuffer:NAME):DEFAULT-BUFFER-HANDLE. IF VALID-HANDLE(hTempBuffer) THEN hDsBuffer:ATTACH-DATA-SOURCE(hTempBuffer). END. /* 生成XML文件 */ hProDataSet:WRITE-XML(FILE, cXmlOutputPath, ?, ?, ?, TRUE, ?, ?, "UTF-8"). /* 清理动态创建的资源 */ DELETE OBJECT hProDataSet. /* 循环删除所有临时表句柄(略,可根据实际创建的临时表逐一清理) */
关键注意事项
- 关联一致性:临时表的外键关联必须与XSD中定义的父子关系完全匹配,包括字段名称、关联规则。
- 关联键维护:填充子记录时必须正确设置父键值,确保ProDataSet能识别父子记录的从属关系。
- 类型转换:异构库字段与XSD字段类型不匹配时,需手动做类型转换(如日期格式、数值精度)。
- 资源清理:动态创建的ProDataSet、临时表、查询句柄使用后必须删除,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Frank Sandbeans
相关产品推荐
相关产品推荐

