I'm having a rather simple XML structure similar to the example below. I'm storing the XML data into XMLTYPE table without modifications and constructing a set of views for SQL access to XML data on top of that. This is very basic and instructed e.g. in
Breaking Up Multiple Levels of XML Data: http://download.oracle.com/docs/cd/E11882_01/appdev.112/e23094/xdb03usg.htm#autoId58
The problem is that XML data is missing an identifier for order elements that could be used as a primary key when splitting document levels (items) for relational views.
Currently I'm planning to construct such an identifier by combining a top level identifier (that is unique) with ordinal position of order elements. Unfortunately I don't know how to do that (see below). My second question is if this is a good idea at all or should something else be used instead.
I'm running Oracle 11.2.0.1.0.
create or replace view orders_view as
with xmldata as (select xmltype('<batch id="batch1">
<order>
<orderer>Joe</orderer>
<items>
<item>Standard widget</item>
</items>
</order>
<order>
<orderer>Jack</orderer>
<items>
<item>Regular widget</item>
<item>Cooling widget</item>
</items>
</order>
<order>
<orderer>John</orderer>
<items>
<item>Super+ widget</item>
<item>Super+ widget</item>
</items>
</order>
</batch>') object_value from dual)
select x1.batchid,
(select x1.batchid || '-' || x2.orderid from dual) as orderid,
x2.orderer_name,
x2.nbr_of_items
from xmldata,
xmltable('$doc/batch' passing xmldata.object_value as "doc"
columns
batchid varchar2(10) path '@id',
orderlist xmltype path 'order') x1,
xmltable('/order' passing x1.orderlist
columns
orderid varchar2(20) path '"?"', /* What to put here to get expected results ? */
orderer_name varchar2(10) path 'orderer',
nbr_of_items number path 'count(items/item)') x2;
column batchid format a10
column orderid format a10
column orderer_name format a10
select * from orders_view;
Expected results:
BATCHID ORDERID ORDERER_NA NBR_OF_ITEMS
---------- ---------- ---------- ------------
batch1 batch1-1 Joe 1
batch1 batch1-2 Jack 2
batch1 batch1-3 John 2
Where ORDERID is constructed as BATCHID + "-" + the position of <order> element in the batch.