PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL में XML फ़ाइलें आयात करें

नेक्रोमैंसिंग:उन लोगों के लिए जिन्हें काम करने के उदाहरण की आवश्यकता है:

DO $$
   DECLARE myxml xml;
BEGIN

myxml := XMLPARSE(DOCUMENT convert_from(pg_read_binary_file('MyData.xml'), 'UTF8'));

DROP TABLE IF EXISTS mytable;
CREATE TEMP TABLE mytable AS 

SELECT 
     (xpath('//ID/text()', x))[1]::text AS id
    ,(xpath('//Name/text()', x))[1]::text AS Name 
    ,(xpath('//RFC/text()', x))[1]::text AS RFC
    ,(xpath('//Text/text()', x))[1]::text AS Text
    ,(xpath('//Desc/text()', x))[1]::text AS Desc
FROM unnest(xpath('//record', myxml)) x
;

END$$;


SELECT * FROM mytable;

या कम शोर के साथ

SELECT 
     (xpath('//ID/text()', myTempTable.myXmlColumn))[1]::text AS id
    ,(xpath('//Name/text()', myTempTable.myXmlColumn))[1]::text AS Name 
    ,(xpath('//RFC/text()', myTempTable.myXmlColumn))[1]::text AS RFC
    ,(xpath('//Text/text()', myTempTable.myXmlColumn))[1]::text AS Text
    ,(xpath('//Desc/text()', myTempTable.myXmlColumn))[1]::text AS Desc
    ,myTempTable.myXmlColumn as myXmlElement
FROM unnest(
    xpath
    (    '//record'
        ,XMLPARSE(DOCUMENT convert_from(pg_read_binary_file('MyData.xml'), 'UTF8'))
    )
) AS myTempTable(myXmlColumn)
;

इस उदाहरण के साथ XML फ़ाइल (MyData.xml):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data-set>
    <record>
        <ID>1</ID>
        <Name>A</Name>
        <RFC>RFC 1035[1]</RFC>
        <Text>Address record</Text>
        <Desc>Returns a 32-bit IPv4 address, most commonly used to map hostnames to an IP address of the host, but it is also used for DNSBLs, storing subnet masks in RFC 1101, etc.</Desc>
    </record>
    <record>
        <ID>2</ID>
        <Name>NS</Name>
        <RFC>RFC 1035[1]</RFC>
        <Text>Name server record</Text>
        <Desc>Delegates a DNS zone to use the given authoritative name servers</Desc>
    </record>
</data-set>

नोट:
MyData.xml को PG_Data निर्देशिका (pg_stat निर्देशिका की मूल-निर्देशिका) में होना चाहिए।
उदा. /var/lib/postgresql/9.3/main/MyData.xml
इसके लिए PostGreSQL 9.1+ की आवश्यकता है

कुल मिलाकर, आप इसे फ़ाइल रहित, इस तरह प्राप्त कर सकते हैं:

SELECT 
     (xpath('//ID/text()', myTempTable.myXmlColumn))[1]::text AS id
    ,(xpath('//Name/text()', myTempTable.myXmlColumn))[1]::text AS Name 
    ,(xpath('//RFC/text()', myTempTable.myXmlColumn))[1]::text AS RFC
    ,(xpath('//Text/text()', myTempTable.myXmlColumn))[1]::text AS Text
    ,(xpath('//Desc/text()', myTempTable.myXmlColumn))[1]::text AS Desc
    ,myTempTable.myXmlColumn as myXmlElement 
    -- Source: https://en.wikipedia.org/wiki/List_of_DNS_record_types
FROM unnest(xpath('//record', 
 CAST('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data-set>
    <record>
        <ID>1</ID>
        <Name>A</Name>
        <RFC>RFC 1035[1]</RFC>
        <Text>Address record</Text>
        <Desc>Returns a 32-bit IPv4 address, most commonly used to map hostnames to an IP address of the host, but it is also used for DNSBLs, storing subnet masks in RFC 1101, etc.</Desc>
    </record>
    <record>
        <ID>2</ID>
        <Name>NS</Name>
        <RFC>RFC 1035[1]</RFC>
        <Text>Name server record</Text>
        <Desc>Delegates a DNS zone to use the given authoritative name servers</Desc>
    </record>
</data-set>
' AS xml)   
)) AS myTempTable(myXmlColumn)
;

ध्यान दें कि MS-SQL के विपरीत, xpath text() NULL मान पर NULL लौटाता है, न कि खाली स्ट्रिंग।
यदि किसी कारण से आपको NULL के अस्तित्व की स्पष्ट रूप से जाँच करने की आवश्यकता है, तो आप [not(@xsi:nil="true")] का उपयोग कर सकते हैं। , जिसमें आपको नामस्थानों की एक सरणी पास करने की आवश्यकता है, क्योंकि अन्यथा, आपको एक त्रुटि मिलती है (हालांकि, आप सभी नामस्थानों को छोड़ सकते हैं लेकिन xsi)।

SELECT 
     (xpath('//xmlEncodeTest[1]/text()', myTempTable.myXmlColumn))[1]::text AS c1

    ,(
    xpath('//xmlEncodeTest[1][not(@xsi:nil="true")]/text()', myTempTable.myXmlColumn
    ,
    ARRAY[
        -- ARRAY['xmlns','http://www.w3.org/1999/xhtml'], -- defaultns
        ARRAY['xsi','http://www.w3.org/2001/XMLSchema-instance'],
        ARRAY['xsd','http://www.w3.org/2001/XMLSchema'],        
        ARRAY['svg','http://www.w3.org/2000/svg'],
        ARRAY['xsl','http://www.w3.org/1999/XSL/Transform']
    ]
    )
    )[1]::text AS c22


    ,(xpath('//nixda[1]/text()', myTempTable.myXmlColumn))[1]::text AS c2 
    --,myTempTable.myXmlColumn as myXmlElement
    ,xmlexists('//xmlEncodeTest[1]' PASSING BY REF myTempTable.myXmlColumn) AS c1e
    ,xmlexists('//nixda[1]' PASSING BY REF myTempTable.myXmlColumn) AS c2e
    ,xmlexists('//xmlEncodeTestAbc[1]' PASSING BY REF myTempTable.myXmlColumn) AS c1ea
FROM unnest(xpath('//row', 
     CAST('<?xml version="1.0" encoding="utf-8"?>
    <table xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <row>
        <xmlEncodeTest xsi:nil="true" />
        <nixda>noob</nixda>
      </row>
    </table>
    ' AS xml)   
    )
) AS myTempTable(myXmlColumn)
;

आप

. करके यह भी जांच सकते हैं कि कोई फ़ील्ड XML-पाठ्य में समाहित है या नहीं
 ,xmlexists('//xmlEncodeTest[1]' PASSING BY REF myTempTable.myXmlColumn) AS c1e

उदाहरण के लिए जब आप सीआरयूडी के लिए संग्रहित प्रक्रिया/फ़ंक्शन में एक्सएमएल-वैल्यू पास करते हैं। (ऊपर देखें)

साथ ही, ध्यान दें कि एक्सएमएल में शून्य-मान पास करने का सही तरीका है <elementName xsi:nil="true" /> और नहीं <elementName /> या कुछ नही। विशेषताओं में NULL पास करने का कोई सही तरीका नहीं है (आप केवल विशेषता को छोड़ सकते हैं, लेकिन फिर बड़े डेटासेट में स्तंभों और उनके नामों की संख्या का अनुमान लगाना मुश्किल/धीमा हो जाता है)।

जैसे

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<table>
    <row column1="a" column2="3" />
    <row column1="b" column2="4" column3="true" />
</table>

(अधिक कॉम्पैक्ट है, लेकिन बहुत खराब है यदि आपको इसे आयात करने की आवश्यकता है, खासकर यदि एक्सएमएल-फाइलों से एकाधिक जीबी डेटा के साथ - स्टैक ओवरफ्लो डेटा डंप में इसका एक अद्भुत उदाहरण देखें)

SELECT 
     myTempTable.myXmlColumn
    ,(xpath('//@column1', myTempTable.myXmlColumn))[1]::text AS c1
    ,(xpath('//@column2', myTempTable.myXmlColumn))[1]::text AS c2
    ,(xpath('//@column3', myTempTable.myXmlColumn))[1]::text AS c3
    ,xmlexists('//@column3' PASSING BY REF myTempTable.myXmlColumn) AS c3e
    ,case when (xpath('//@column3', myTempTable.myXmlColumn))[1]::text is null then 1 else 0 end AS is_null 
FROM unnest(xpath('//row', '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<table>
    <row column1="a" column2="3" />
    <row column1="b" column2="4" column3="true" />
</table>'
))  AS myTempTable(myXmlColumn) 


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. धाराप्रवाह NHibernate और PostgreSQL, SchemaMetadataUpdater.QuoteTableAndColumns - System.NotSupportedException:निर्दिष्ट विधि समर्थित नहीं है

  2. मेरे पसंदीदा पोस्टग्रेएसक्यूएल प्रश्नों में से अधिक - और वे भी क्यों मायने रखते हैं

  3. PostgreSQL में डेटाबेस की एक कॉपी बनाना

  4. PostgreSQL ROLE (उपयोगकर्ता) बनाएं यदि यह मौजूद नहीं है

  5. रेल और पोस्टग्रेएसक्यूएल में समय क्षेत्र को पूरी तरह से अनदेखा करना