My intention is to "select the data where container number is equals to input data" (kind of search functionality). I am facing an issue when I am trying to retrieve the data, with a problem at where condition:
d:goodsShipments/d:consignment/d:transportEquipment/d:id/text()
Here I am getting multiple data. I don't know how to iterate it in the where condition.
My query is:
My source XML is:
How i can select all the declaration where sealId is 5678?
how deal with the where condition in this case?
You have multiple containers per consignment, and you're filtering based on LRN after extracting that from the raw XML; so you need to use nested XMLTable objects. The first one gets the data from the declaration and extracts the consignments as a sub-XMLType. That is then passed to the second XMLTable which extracts the container information.
SELECT x1.lrn, x1.username, x2.containerNumber
FROM dmsimport_decl d
CROSS JOIN XMLTable(
XMLNAMESPACES(DEFAULT 'http://www.xxxx.invalid/xxxx/xxx/schema/xxx',
'http://www.xxxx.invalid/xxx/schema/common' AS "c",
'http://www.xxxx.invalid/xxxx/xxx/schema/xxx' AS "d"),
'/d:declaration'
PASSING d.object_value
COLUMNS
lrn VARCHAR2(35 CHAR)
PATH 'c:declarationHeader/c:localReferenceNumber/text()',
username CHAR(25)
PATH 'c:declarationHeader/c:username/text()',
consignment XMLType
PATH 'd:goodsShipments/d:consignment'
) x1
CROSS JOIN XMLTable(
XMLNAMESPACES(DEFAULT 'http://www.xxxx.invalid/xxxx/xxx/schema/xxx',
'http://www.xxxx.invalid/xxx/schema/common' AS "c",
'http://www.xxxx.invalid/xxxx/xxx/schema/xxx' AS "d"),
'//d:transportEquipment'
PASSING x1.consignment
COLUMNS
containerNumber VARCHAR2(35 CHAR)
PATH 'd:id/text()'
) x2
WHERE x1.lrn = 'NLDMS111111150010950';
With your (updated) sample XML, that produces:
LRN USERNAME CONTAINERNUMBER
----------------------------------- ------------------------- -----------------------------------
NLDMS111111150010950 testSC testSC abcd
NLDMS111111150010950 testSC testSC bcde
NLDMS111111150010950 testSC testSC cdef
NLDMS111111150010950 testSC testSC defg
NLDMS111111150010950 testSC testSC efgh
Hopefully that is what you want to see.
Quick SQL Fiddle demo.
You could also use a more complicated XPath to keep it within a single XMLTable, but I think this is clearer.
You can use the below query to iterate and get the id's from container component..
SELECT x1.lrn, x1.username, x2.containerNumber
FROM dmsimport_decl d
CROSS JOIN XMLTable(
XMLNAMESPACES(DEFAULT 'http://www.SSSSSSS/dmsimport',
'http://www.SSSSSSScommon' AS "c",
'http://www.SSSSSSSS/dmsimport' AS "d"),
'/d:declaration'
PASSING d.object_value
COLUMNS
lrn VARCHAR2(35 CHAR)
PATH 'c:declarationHeader/c:localReferenceNumber/text()',
username CHAR(25)
PATH 'c:declarationHeader/c:username/text()',
containerComponent XMLType
PATH 'd:goodsShipments/d:goodsItems'
) x1.
CROSS JOIN XMLTable(
XMLNAMESPACES(DEFAULT 'http://www.SSSSSSSSS/dmsimport',
'http://www.SSSSSS/common' AS "c",
'http://www.SSSSSSSS/dmsimport' AS "d"),
'//d:containerComponent'
PASSING x1.containerComponent
COLUMNS
containerNumber VARCHAR2(35 CHAR)
PATH 'd:id/text()'
) x2
WHERE x1.lrn = 'NL123456789160000464';