下面我有XML我必须导入POSTGresQL数据库。
似乎没什么用。
每个客户都有多个属性。
需要导入到这样的表中:
create table CustomerAttXML (
CustomerID varchar(30) NULL,
AttributeUID varchar(30) NULL,
AttributeName varchar(50) NULL,
AttributeValue varchar(50) NULL,
AttributeUIDValue varchar(50) NULL);
我几乎放弃了。
有没有人有任何想法?
<?xml version="1.0"?>
<Customers>
<Customer>
<customerId>C00100000</customerId>
<title/>
<firstName>Mary</firstName>
<lastName>Kennedy</lastName>
<dob/>
<mobilePhone>Customer Declined</mobilePhone>
<primaryEmail>Customer Declined</primaryEmail>
<primaryAddress1>Customer Declined</primaryAddress1>
<primaryAddress2>Customer Declined</primaryAddress2>
<primaryCity>Customer Declined</primaryCity>
<stateName>Customer Declined</stateName>
<countryName>Customer Declined</countryName>
<countryCode>36</countryCode>
<primaryPostCode>3227</primaryPostCode>
<homePhone>52222640</homePhone>
<workPhone/>
<subscribeToEmail>false</subscribeToEmail>
<subscribeToSMS>true</subscribeToSMS>
<Attributes>
<Attribute>
<attributeUid>13</attributeUid>
<attributeValue>false</attributeValue>
<attribDesc>Inactive Flag</attribDesc>
<attributeUidValue/>
</Attribute>
<Attribute>
<attributeUid>9</attributeUid>
<attributeValue>false</attributeValue>
<attribDesc>Flea & Worming purchase</attribDesc>
<attributeUidValue/>
</Attribute>
<Attribute>
<attributeUid>7</attributeUid>
<attributeValue>9308</attributeValue>
<attribDesc>Store Code</attribDesc>
<attributeUidValue>0001 Transylvania</attributeUidValue>
</Attribute>
<Attribute>
<attributeUid>16</attributeUid>
<attributeValue>SODOFF</attributeValue>
<attribDesc>PasswordClearText</attribDesc>
<attributeUidValue/>
</Attribute>
</Attributes>
</Customer>
<Customer>
<customerId>C00121000</customerId>
<title/>
<firstName>Cherie</firstName>
<lastName>Selby</lastName>
<dob/>
<mobilePhone>Customer Declined</mobilePhone>
<primaryEmail>jCustomer Declinedm</primaryEmail>
<primaryAddress1>Customer Declined</primaryAddress1>
<primaryAddress2></primaryAddress2>
<primaryCity>Customer Declinedl</primaryCity>
<stateName>Customer Declined</stateName>
<countryName>Customer Declined</countryName>
<countryCode>36</countryCode>
<primaryPostCode>Customer Declined</primaryPostCode>
<homePhone>Customer Declined</homePhone>
<workPhone/>
<subscribeToEmail>true</subscribeToEmail>
<subscribeToSMS>true</subscribeToSMS>
<Attributes>
<Attribute>
<attributeUid>9</attributeUid>
<attributeValue>false</attributeValue>
<attribDesc>Flea & Worming purchase</attribDesc>
<attributeUidValue/>
</Attribute>
<Attribute>
<attributeUid>13</attributeUid>
<attributeValue>false</attributeValue>
<attribDesc>Inactive Flag</attribDesc>
<attributeUidValue/>
</Attribute>
<Attribute>
<attributeUid>16</attributeUid>
<attributeValue>Customer Declined</attributeValue>
<attribDesc>PasswordClearText</attribDesc>
<attributeUidValue/>
</Attribute>
<Attribute>
<attributeUid>7</attributeUid>
<attributeValue>Customer Declined</attributeValue>
<attribDesc>Store Code</attribDesc>
<attributeUidValue>Customer Declined</attributeUidValue>
</Attribute>
</Attributes>
</Customer>
</Customers>
这是我目前无法解决的解决方案:
CREATE OR REPLACE FUNCTION public.import_custxmlattributes ( filename text )
RETURNS VOID AS
'
declare
myxml xml;
datafile text := $1;
EachCustRecord RECORD;
EachAttrRecord RECORD;
begin
drop table if exists byteb_v;
create temp table byteb_v AS
select bytea_import(datafile);
myxml := (select cast(encode(bytea_import,''escape'') as xml) from byteb_v) ;
drop table if exists CustomerAttXML;
create table CustomerAttXML (
CustomerID varchar(30) NULL,
AttributeUID varchar(30) NULL,
AttributeName varchar(50) NULL,
AttributeValue varchar(50) NULL,
AttributeUIDValue varchar(50) NULL);
for EachCustRecord in
select extract_value(''/Customer/customerId'', x) AS CustomerID,x as individual
FROM unnest(xpath(''/Customers/Customer'', (select cast(encode(bytea_import,''escape'') as xml) from byteb_v))) x LOOP
FOR EachAttrRecord IN
SELECT xpath(''//Attributes/Attribute/attributeUid/text()'', EachCustRecord.individual ) AS AttributeUID,
xpath(''//Attributes/Attribute/attribDesc/text()'', EachCustRecord.individual) AS AttributeName,
xpath(''//Attributes/Attribute/attributeValue/text()'', EachCustRecord.individual) AS AttributeValue,
xpath(''//Attributes/Attribute/attributeUidValue/text()'', EachCustRecord.individual) AS AttributeUIDValue
FROM unnest(xpath(''/Customers/Customer'', (select cast(encode(bytea_import,''escape'') as xml) from byteb_v))) x LOOP
RAISE NOTICE ''EachCustRecord.CustomerID(%)'', EachCustRecord.CustomerID;
RAISE NOTICE ''EachAttrRecord.AttributeUID(%)'', EachAttrRecord.AttributeUID;
RAISE NOTICE ''EachAttrRecord.AttributeName(%)'', EachAttrRecord.AttributeName;
RAISE NOTICE ''EachAttrRecord.AttributeValue(%)'', EachAttrRecord.AttributeValue;
RAISE NOTICE ''EachAttrRecord.AttributeUIDValue(%)'', EachAttrRecord.AttributeUIDValue;
/* insert into CustomerAttXML
(CustomerID,AttributeUID,AttributeName,AttributeValue,AttributeUIDValue)
values
( EachCustRecord.CustomerID, EachAttrRecord.AttributeUID, EachAttrRecord.AttributeName, EachAttrRecord.AttributeValue, EachAttrRecord.AttributeUIDValue ); */
END LOOP;
END LOOP;
select pg_sleep(10);
end;'
LANGUAGE 'plpgsql';
答案 0 :(得分:0)
从Import XML files to PostgreSQL中汲取灵感,但在嵌套循环中完成,以避免从错误的分支中提取值...
CREATE or REPLACE function customerExtractFromXml()
RETURNS TABLE (custid text, atuid text, atdesc text, atval text, atuval text) as $$
DECLARE
thexml xml := ('<?xml version="1.0"?>
<Customers>
<Customer>
<customerId>C00100000</customerId>
<title/>
<firstName>Mary</firstName>
<lastName>Kennedy</lastName>
<dob/>
<mobilePhone>Customer Declined</mobilePhone>
<primaryEmail>Customer Declined</primaryEmail>
<primaryAddress1>Customer Declined</primaryAddress1>
<primaryAddress2>Customer Declined</primaryAddress2>
<primaryCity>Customer Declined</primaryCity>
<stateName>Customer Declined</stateName>
<countryName>Customer Declined</countryName>
<countryCode>36</countryCode>
<primaryPostCode>3227</primaryPostCode>
<homePhone>52222640</homePhone>
<workPhone/>
<subscribeToEmail>false</subscribeToEmail>
<subscribeToSMS>true</subscribeToSMS>
<Attributes>
<Attribute>
<attributeUid>13</attributeUid>
<attributeValue>false</attributeValue>
<attribDesc>Inactive Flag</attribDesc>
<attributeUidValue/>
</Attribute>
<Attribute>
<attributeUid>9</attributeUid>
<attributeValue>false</attributeValue>
<attribDesc>Flea & Worming purchase</attribDesc>
<attributeUidValue/>
</Attribute>
<Attribute>
<attributeUid>7</attributeUid>
<attributeValue>9308</attributeValue>
<attribDesc>Store Code</attribDesc>
<attributeUidValue>0001 Transylvania</attributeUidValue>
</Attribute>
<Attribute>
<attributeUid>16</attributeUid>
<attributeValue>SODOFF</attributeValue>
<attribDesc>PasswordClearText</attribDesc>
<attributeUidValue/>
</Attribute>
</Attributes>
</Customer>
<Customer>
<customerId>C00121000</customerId>
<title/>
<firstName>Cherie</firstName>
<lastName>Selby</lastName>
<dob/>
<mobilePhone>Customer Declined</mobilePhone>
<primaryEmail>jCustomer Declinedm</primaryEmail>
<primaryAddress1>Customer Declined</primaryAddress1>
<primaryAddress2></primaryAddress2>
<primaryCity>Customer Declinedl</primaryCity>
<stateName>Customer Declined</stateName>
<countryName>Customer Declined</countryName>
<countryCode>36</countryCode>
<primaryPostCode>Customer Declined</primaryPostCode>
<homePhone>Customer Declined</homePhone>
<workPhone/>
<subscribeToEmail>true</subscribeToEmail>
<subscribeToSMS>true</subscribeToSMS>
<Attributes>
<Attribute>
<attributeUid>9</attributeUid>
<attributeValue>false</attributeValue>
<attribDesc>Flea & Worming purchase</attribDesc>
<attributeUidValue/>
</Attribute>
<Attribute>
<attributeUid>13</attributeUid>
<attributeValue>false</attributeValue>
<attribDesc>Inactive Flag</attribDesc>
<attributeUidValue/>
</Attribute>
<Attribute>
<attributeUid>16</attributeUid>
<attributeValue>Customer Declined</attributeValue>
<attribDesc>PasswordClearText</attribDesc>
<attributeUidValue/>
</Attribute>
<Attribute>
<attributeUid>7</attributeUid>
<attributeValue>Customer Declined</attributeValue>
<attribDesc>Store Code</attribDesc>
<attributeUidValue>Customer Declined</attributeUidValue>
</Attribute>
</Attributes>
</Customer>
</Customers>
')::xml;
customer text;
attribute xml;
BEGIN
foreach customer in array xpath('//customerId/text()', thexml) LOOP
foreach attribute in array xpath('//customerId[.='''||customer||''']/../Attributes/Attribute', thexml) LOOP
custid := customer;
atuid := (xpath('attributeUid/text()', attribute))[1];
atdesc := (xpath('attribDesc/text()', attribute))[1];
atval := (xpath('attributeValue/text()', attribute))[1];
atuval := (xpath('attributeUidValue/text()', attribute))[1];
return next ;
END LOOP;
END LOOP;
END;
$$ LANGUAGE plpgsql;
select * from customerExtractFromXml();
运行此结果:
custid | atuid | atdesc | atval | atuval
-----------+-------+-----------------------------+-------------------+-------------------
C00100000 | 13 | Inactive Flag | false |
C00100000 | 9 | Flea & Worming purchase | false |
C00100000 | 7 | Store Code | 9308 | 0001 Transylvania
C00100000 | 16 | PasswordClearText | SODOFF |
C00121000 | 9 | Flea & Worming purchase | false |
C00121000 | 13 | Inactive Flag | false |
C00121000 | 16 | PasswordClearText | Customer Declined |
C00121000 | 7 | Store Code | Customer Declined | Customer Declined
(8 rows)
缩小它将处理的XML部分是关键 - 可能有更有效的方法,可能只使用xpath(尽管可能仅使用xpath v2),我不知道。
灰