Hello Francesco,
I'm not sure what your XML file looks like but I've made good experiences with the following approach for flatteing a BMECat file (
https://help.sap.com/docs/ARIBA_NETWORK_SUPPLIERS/c8ad7036e6104bfaa33ec523991a6727/65b815e1ae724ce38d02b0fb9faefc7d.html?locale=en-US) to a dynamic array.
type dt_boolean boolean,
dt_count integer,
dt_datetime string,
dt_datetype date,
dt_duration string,
dt_float float,
dt_integer integer,
dt_lang char(3),
dt_string string,
t_new_catalog record
attr_prev_version dt_integer,
feature_system t_feature_system,
classification_system dynamic array of t_classification_system,
catalog_group_system t_catalog_group_system,
formulas t_formulas,
ipp_definitions t_ipp_definitions,
product dynamic array of t_product,
product_to_cataloggroup_map dynamic array of t_product_to_cataloggroup_map,
article dynamic array of t_article,
article_to_cataloggroup_map dynamic array of t_article_to_cataloggroup_map
end record,
t_update_products record
attr_prev_version dt_integer,
formulas t_formulas,
product dynamic array of t_product,
product_to_cataloggroup_map dynamic array of t_product_to_cataloggroup_map,n
article dynamic array of t_article,
article_to_cataloggroup_map dynamic array of t_article_to_cataloggroup_map
end record,
t_update_prices record
attr_prev_version dt_integer,
formulas t_formulas,
product dynamic array of t_product,
article dynamic array of t_article
end record
type t_bmecat record # root element
attr_version dt_string,
header t_header,
new_catalog t_new_catalog,
update_products t_update_products,
update_prices t_update_prices
end record
define l_xml xml.domdocument,
l_bmecat t_bmecat
if ((l_xml := xml.domdocument.create()) is not null)
then try
call l_xml.load("/path/to/xml-file.xml")
catch
if (l_xml.geterrorscount() > 0)
then for i = 1 to l_xml.geterrorscount()
error sfmt("error %1: %2", i, l_xml.geterrordescription(i))
end for
else error fmt("error while loading XML file %1", l_filename)
end if
end try
message "parsing BMECat-data..."
call parse_bmecat(l_xml) returning l_bmecat.*
end if
...
public function parse_bmecat (l_xml xml.domdocument)
returns (t_bmecat)
define l_bmecat t_bmecat,
l_node xml.domnode
initialize l_bmecat to null
if (l_xml.getdocumentnodescount() > 0)
then if ((l_node := l_xml.getfirstdocumentnode()) is not null)
then while (l_node.getnodetype() <> "ELEMENT_NODE")
let l_node = l_node.getnextsibling()
end while
if (l_node is not null)
then if (l_node.getlocalname() == "BMECAT")
then if l_node.hasattribute("version")
then let l_bmecat.attr_version = l_node.getattribute("version")
let l_node = l_node.getfirstchild()
while (l_node is not null)
case l_node.getlocalname()
when "HEADER"
call parse_header(l_node) returning l_bmecat.header.*
when "T_NEW_CATALOG"
call parse_t_new_catalog(l_node) returning l_bmecat.new_catalog.*
when "T_UPDATE_PRODUCTS"
call parse_t_update_products(l_node) returning l_bmecat.update_products.*
when "T_UPDATE_PRICES"
call parse_t_update_prices(l_node) returning l_bmecat.update_prices.*
when "#comment"
when "#text"
otherwise
message sfmt("unknown Element %1", l_node.getlocalname())
end case
let l_node = l_node.getnextsibling()
end while
else error "BMECAT Attribute version missing!"
end if
else error "no valid BMECat file!"
end if
end if
else error "no valid BMECat file!"
end if
else error "not valid BMECat file!"
end if
return l_bmecat.*
end function
The type t_bmecat is formed recursively from the subelements and is not described here because the full definition is too long. The routines for parsing the individual sub-elements have essentially the same structure as the function above and only need to be adapted with regard to the elements used.
Each function will traverse one element from top to bottom and read the contents into the corresponding entry within the array. I'm not sure if this is the best, easiest, most elegant or most performant way but it works quite good.
Maybe this small code snippet will help you further.
Good luck and kind regards
Roland