json – Create tables from XML dynamically using Postgres sql script
I’m trying to create postgres sql tables and add columns & its values as a json blob to a Data column of the newly created table.
I can create the table successfully, however, I’m unable to insert the data.
Here’s my postgres sql script:
DO $$
DECLARE
xml_data TEXT;
container_table_name TEXT;
doc XML;
containers XML[];
container_element XML;
column_elements XML[];
column_element XML;
jsonb_data JSONB;
column_name TEXT;
column_value TEXT;
BEGIN
-- Load your XML data into xml_data variable
xml_data := E'
<Root>
<ClientContainer RecordCount="1">
<Client>
<Name>Test Client</Name>
<Address>469 LaTrobe St, Melbourne</Address>
<Mobile>0411223344</Mobile>
</Client>
</ClientContainer>
<AccountContainer RecordCount="1">
<Account>
<Name>Test Account</Name>
<Type>Super</Type>
</Account>
</AccountContainer>
</Root>';
-- Convert text to XML type for processing
doc := XMLPARSE(DOCUMENT xml_data);
-- Extract container elements
containers := xpath('/Root/*[contains(local-name(), "Container")]', doc);
-- Loop through each container to create tables and columns
FOREACH container_element IN ARRAY containers LOOP
-- Get the table name from the container element's name, removing 'Container' from it
container_table_name := split_part((xpath('local-name(./child::*[1])', container_element))[1]::TEXT, 'Container', 1);
-- Create the table if it does not exist with a JSONB column for data
EXECUTE format('CREATE TABLE IF NOT EXISTS %I (data JSONB);', container_table_name);
-- Extract all child elements of the first child element under the container element
column_elements := xpath('(./child::*[position()=1]/child::*)', container_element);
-- Initialize jsonb_data as an empty JSON object
jsonb_data := '{}'::JSONB;
-- Loop through each child element to build a JSONB object
FOREACH column_element IN ARRAY column_elements LOOP
RAISE NOTICE 'Column Element: %', column_element;
column_name := (xpath('local-name(.)', column_element))[1]::TEXT;
column_value := (xpath('text()', column_element))[1]::TEXT;
jsonb_data := jsonb_set(jsonb_data, ARRAY[column_name], to_jsonb(column_value));
END LOOP;
-- Insert the JSONB data into the table
EXECUTE format('INSERT INTO %I (data) VALUES (%L);', container_table_name, jsonb_data);
END LOOP;
END $$;
*the above script should create Client & Account tables and insert json data as below:
`
“Client”: {
“Name”: “Test Client”,
“Address”: “469 LaTrobe St, Melbourne”,
“Mobile”: “0411223344”
}
"Account": {
"Name": "Test Account",
"Type": "Super"
}
`
Read more here: Source link
