xpath_table and namespaces

Allgemeines zu PostgreSQL.
Antworten
schoetbi
Benutzer
Beiträge: 41
Registriert: Di 12. Aug 2008, 21:22

xpath_table and namespaces

Beitrag von schoetbi » Do 3. Mai 2018, 08:26

Hallo,

ich würde gerne die Funtkion xpath_table verwenden, allerding hat mein XML Namespaces und ich verstehe nicht wo ich für die XPATH Expressions die Namespaces angeben kann.

In der Doku finde ich leider nichts: https://www.postgresql.org/docs/9.1/sta ... #AEN145365

Kennt jemand eine Möglichkeit die Namespaces anzugeben?

Danke,
Tobias

castorp
Erfahrener Benutzer
Beiträge: 1060
Registriert: Sa 27. Jun 2009, 22:24
Wohnort: Bayern

Re: xpath_table and namespaces

Beitrag von castorp » Do 3. Mai 2018, 08:49

Kannst Du mal ein Beispiel Deines XML zeigen? (bitte mit [code]...[/code] tags formatieren, damit es lesbar ist)

Verwendest Du wirklich noch Postgres 9.1?
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

schoetbi
Benutzer
Beiträge: 41
Registriert: Di 12. Aug 2008, 21:22

Re: xpath_table and namespaces

Beitrag von schoetbi » Do 3. Mai 2018, 09:48

Hier ist ein Beispiel:

Code: Alles auswählen

<TestSequence 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns="http://www.company.com/product/specification"
  Name="new sequence.001" 
  ID="0999fbaf-c696-4b06-b4b1-489bcc123b9a" 
  InternalId="0" 
  RepeatCounter="1" />  
    <TestBlockLink Id="fff6f74e-0ee4-4c70-9cf8-f1f27e5f4391" Name="Reset" InternalId="1" 
                           IdLinkedBlock="b71c0f05-00b5-4086-a1e8-574094565986" RepeatCounter="123" />
    <TestBlockLink Id="f8c6b3a5-0491-4969-bab7-3cf606217e67" Name="Switch_1" InternalId="2" 
                           IdLinkedBlock="1b5e0458-a383-468d-ab44-1468d783aab0" />
    <TestBlockLink Id="80ffd8c7-90c2-4b99-bc3c-bffa37827784" Name="1234" InternalId="3" 
                           IdLinkedBlock="c889b9b9-a5f6-4388-8d87-8fff6734bcbc" />
</TestSequence>
versucht habe ich es mit

Code: Alles auswählen

SELECT * FROM
xpath_table('id',
            'xmldata',
            'tpa.testelement',
            '//TestBlockLink/@Id|//TestBlockLink/@Name|//TestBlockLink/@RepeatCounter|//TestBlockLink/@IdLinkedBlock',
            'true')
AS t(id uuid, linkid uuid, name text, loops integer, idlinkedblock uuid);
Nein ich verwende nicht mehr 9.1, das war nur das Ergebnis der Google-Suche, als ich nach der Doku gesucht habe.

castorp
Erfahrener Benutzer
Beiträge: 1060
Registriert: Sa 27. Jun 2009, 22:24
Wohnort: Bayern

Re: xpath_table and namespaces

Beitrag von castorp » Do 3. Mai 2018, 10:32

Ich glaube nicht, dass man mit xpath_table namespaces übergeben kann, aber mit Postgres 10 kannst Du das so machen:

Code: Alles auswählen

select x.*
from testelement, 
     xmltable(
        xmlnamespaces('http://www.company.com/product/specification' as ps), 
        '//ps:TestBlockLink' passing xmldata
        columns id uuid path '@Id', 
                name text path '@Name', 
                loops int path '@RepeatCounter', 
                id_linked_block uuid path '@IdLinkedBlock') as x
Online Beispiel: https://dbfiddle.uk/?rdbms=postgres_10& ... 8ac5f57b17

Mit 9.6 oder früher, wird es etwas hässlicher:

Code: Alles auswählen

with namespaces (nsp) as (
  values ( array[array['ps', 'http://www.company.com/product/specification']] )
)
select (xpath('//ps:TestBlockLink/@Id', t.xmldata, nsp))[1]::text::uuid as id, 
       (xpath('//ps:TestBlockLink/@Name', t.xmldata, nsp))[1]::text as name,
       (xpath('//ps:TestBlockLink/@RepeatCounter', t.xmldata, nsp))[1]::text::int as loops,
       (xpath('//ps:TestBlockLink/@IdLinkedBlock', t.xmldata, nsp))[1]::text::uuid as id_linked_block
from testelement t,  
     namespaces
Die xpath() Funktion liefert ein Array mit allen gefundenen XML Elementen zurück. Man kann da aber nicht mit | arbeiten, weil das resultierende array nur die gefundenen Elemente enthält, nicht etwa einen "NULL" Wert für Element die über den XPATH Ausdruck nicht gefunden wurden. Die CTE mit dem Namespace array ist nur eine Vereinfachung, damit man das nicht bei jedem xpath() Aufruf wieder hinschreiben muss.
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'

schoetbi
Benutzer
Beiträge: 41
Registriert: Di 12. Aug 2008, 21:22

Re: xpath_table and namespaces

Beitrag von schoetbi » Do 3. Mai 2018, 10:55

Schade, dass ich im Moment nicht auf PG10 wechseln kann. Aber auch das Beispiel mit den CTEs ist sehr hilfreich. Vielen Dank. So komme ich weiter.

Antworten