I would like to be able to extract specific data from a XML type using Oracle in my example for the customer named "Arshad Ali"
This is my xml data that was inserted:
<Customers>
<Customer CustomerName="Arshad Ali" CustomerID="C001">
<Orders>
<Order OrderDate="2012-07-04T00:00:00" OrderID="10248">
<OrderDetail Quantity="5" ProductID="10" />
<OrderDetail Quantity="12" ProductID="11" />
<OrderDetail Quantity="10" ProductID="42" />
</Order>
</Orders>
<Address> Address line 1, 2, 3</Address>
</Customer>
<Customer CustomerName="Paul Henriot" CustomerID="C002">
<Orders>
<Order OrderDate="2011-07-04T00:00:00" OrderID="10245">
<OrderDetail Quantity="12" ProductID="11" />
<OrderDetail Quantity="10" ProductID="42" />
</Order>
</Orders>
<Address> Address line 5, 6, 7</Address>
</Customer>
<Customer CustomerName="Carlos Gonzlez" CustomerID="C003">
<Orders>
<Order OrderDate="2012-08-16T00:00:00" OrderID="10283">
<OrderDetail Quantity="3" ProductID="72" />
</Order>
</Orders>
<Address> Address line 1, 4, 5</Address>
</Customer>
</Customers>
</ROOT>
using get clob I was able to extract all of the customers.
Was wondering if anyone could help me extract data for a specific customer.. tried using the following but was unsuccessful
SELECT extract(OBJECT_VALUE, '/root/Customers') "customer"
FROM mytable2
WHERE existsNode(OBJECT_VALUE, '/customers[CustomerName="Arshad Ali" CustomerID="C001"]')
= 1;
The case and exact names of the XML nodes matter:
SELECT extract(OBJECT_VALUE,
'/ROOT/Customers/Customer[#CustomerName="Arshad Ali"][#CustomerID="C001"]') "customer"
FROM mytable2
WHERE existsnode (OBJECT_VALUE,
'/ROOT/Customers/Customer[#CustomerName="Arshad Ali"][#CustomerID="C001"]') = 1
db<>fiddle
If you only want to search by name then only use that attribute:
SELECT extract(OBJECT_VALUE,
'/ROOT/Customers/Customer[#CustomerName="Arshad Ali"]') "customer"
FROM mytable2
WHERE existsnode (OBJECT_VALUE,
'/ROOT/Customers/Customer[#CustomerName="Arshad Ali"]') = 1
But extract() and existsnode() are deprecated; use xmlquery() and xmlexists() instead:
SELECT xmlquery('/ROOT/Customers/Customer[#CustomerName="Arshad Ali"][#CustomerID="C001"]'
passing object_value
returning content) "customer"
FROM mytable2
WHERE xmlexists('/ROOT/Customers/Customer[#CustomerName="Arshad Ali"][#CustomerID="C001"]'
passing object_value)
db<>fiddle
Related
I currently have a payload that was generated by oracle xml gateway that I need to pull some exact information out. The payload information is store within a db table meaning that I am attempting to us regexp_substr to accomplish this task.
This is the tag that is in the middle of the XML document
<IDCODE>S2200</IDCODE>
"<?xml version="1.0" encoding="UTF-8" standalone='no'?>
<!DOCTYPE PROCESS_INVOICE_002 SYSTEM "asfasdf.dtd">
<!-- Oracle eXtensible Markup Language Gateway Server -->
<PROCESS_INVOICE_002>
<CNTROLAREA>
<BSR>
<VERB value="PROCESS"/>
<NOUN value="INVOICE"/>
<REVISION value="002"/>
</BSR>
<SENDER>
<LOGICALID/>
<COMPONENT/>
<TASK/>
<REFERENCEID/>
<CONFIRMATION/>
<LANGUAGE/>
<CODEPAGE/>
<AUTHID/>
</SENDER>
<DATETIME qualifier="CREATION">
<YEAR/>
<MONTH/>
<DAY/>
<HOUR/>
<MINUTE/>
<SECOND/>
<SUBSECOND/>
<TIMEZONE/>
</DATETIME>
</CNTROLAREA>
<DATAAREA>
<PROCESS_INVOICE>
<INVHEADER>
<AMOUNT qualifier="DOCUMENT" type="T" index="1">
<VALUE>78538</VALUE>
<NUMOFDEC>8</NUMOFDEC>
<SIGN>+</SIGN>
<CURRENCY>USD</CURRENCY>
<DRCR>D</DRCR>
</AMOUNT>
<DATETIME qualifier="DOCUMENT" index="1">
<YEAR>2020</YEAR>
<MONTH>11</MONTH>
<DAY>28</DAY>
<HOUR>00</HOUR>
<MINUTE>00</MINUTE>
<SECOND>00</SECOND>
<SUBSECOND>0000</SUBSECOND>
<TIMEZONE>+0000</TIMEZONE>
</DATETIME>
<DOCUMENTID>81989184</DOCUMENTID>
<DESCRIPTN/>
<DOCTYPE>INV</DOCTYPE>
<PAYMETHOD/>
<REASONCODE/>
<USERAREA>
<NOTEREFCODE/>
<NOTESREF/>
<VENDNUMQUAL>IA</VENDNUMQUAL>
<VENDNUM>98181</VENDNUM>
<DEPTNUMQUAL>DP</DEPTNUMQUAL>
<DEPTNUM>85</DEPTNUM>
<ORDNUMQUAL/>
<ORDNUM>0</ORDNUM>
<CUSTCODEQUAL/>
<CUSTCODE/>
<NETDAYS/>
<DATETIMEQUAL/>
<FOBCODE/>
<UOM/>
<TOTALQUANTITY/>
</USERAREA>
<PARTNER>
<NAME index="1">COMPANY NAME</NAME>
<ONETIME/>
<PARTNRID/>
<PARTNRTYPE>Supplier</PARTNRTYPE>
<SYNCIND/>
<ACTIVE/>
<CURRENCY/>
<DESCRIPTN/>
<DUNSNUMBER/>
<GLENTITYS/>
<PARENTID/>
<PARTNRIDX/>
<PARTNRRATG/>
<PARTNRROLE/>
<PAYMETHOD/>
<TAXEXEMPT/>
<TAXID/>
<TERMID/>
<USERAREA>
<IDQUAL/>
<IDCODE/>
</USERAREA>
<CONTACT>
<NAME index="1">PROFILE</NAME>
<CONTCTTYPE/>
<DESCRIPTN/>
<EMAIL/>
<FAX index="1"/>
<TELEPHONE index="1"/>
<USERAREA/>
</CONTACT>
</PARTNER>
<PARTNER>
<NAME index="1">CUSTOMER NAME</NAME>
<ONETIME/>
<PARTNRID>981698198</PARTNRID>
<PARTNRTYPE>ShipTo</PARTNRTYPE>
<SYNCIND/>
<ACTIVE/>
<CURRENCY/>
<DESCRIPTN/>
<DUNSNUMBER/>
<GLENTITYS/>
<PARENTID/>
<PARTNRIDX/>
<PARTNRRATG/>
<PARTNRROLE/>
<PAYMETHOD/>
<TAXEXEMPT/>
<TAXID/>
<TERMID/>
<USERAREA>
<IDQUAL>ZZ</IDQUAL>
<IDCODE>S2200</IDCODE>
</USERAREA>
<ADDRESS>
<ADDRLINE index="1">123 MAIN STREET</ADDRLINE>
<ADDRTYPE/>
<CITY>HAM CITY</CITY>
<COUNTRY>United States</COUNTRY>
<COUNTY>NEW YORK</COUNTY>
<DESCRIPTN/>
<FAX index="1"/>
<POSTALCODE>18080</POSTALCODE>
<REGION/>
<STATEPROVN>NY</STATEPROVN>
<TAXJRSDCTN/>
<TELEPHONE index="1"/>
<URL/>
<USERAREA/>
</ADDRESS>
REGEX that I am using in the query
TRIM(regexp_substr(ed.payload, '?.+(</IDCODE>)')) Store_NUM,
TRIM(regexp_substr(ed.payload, '(^IDCODE)?.+(</IDCODE>)')) Store_Number
The Outcome that I am receiving from the above SQL regexp_substr. The issue is that I have made it to the correct tab but I can't figure out how to strip the \<IDCODE> and the \</IDCODE> for the output
-Field can have 4 or 5 chars
-letters or numbers
<IDCODE>S2200</IDCODE> Store_NUM
<IDCODE>S2200</IDCODE> Store_Number
I believe you are looking for this if I am understanding you correctly. Return everything in the group between the tags.
SELECT REGEXP_SUBSTR('<IDCODE>S2200</IDCODE>', '<IDCODE>(.*)</IDCODE>', 1, 1, NULL, 1) Store_Number
from dual;
STORE_NUMBER
------------
S2200
1 row selected.
I am trying to find the value of an element / attribute regardless of where it exists in the XML.
XML:
<?xml version="1.0" encoding="UTF-8"?>
<cXML payloadID="12345677-12345567" timestamp="2017-07-26T09:11:05">
<Header>
<From>
<Credential domain="1212">
<Identity>01235 </Identity>
<SharedSecret/>
</Credential>
</From>
<To>
<Credential domain="1212">
<Identity>01234</Identity>
</Credential>
</To>
<Sender>
<UserAgent/>
<Credential domain="8989">
<Identity>10678</Identity>
<SharedSecret>Testing123</SharedSecret>
</Credential>
</Sender>
</Header>
<Request deploymentMode="Prod">
<ConfirmationRequest>
<ConfirmationHeader noticeDate="2017-07-26T09:11:05" operation="update" type="detail">
<Total>
<Money>0.00</Money>
</Total>
<Shipping>
<Description>Delivery</Description>
</Shipping>
<Comments>WO# generated</Comments>
</ConfirmationHeader>
<OrderReference orderDate="2017-07-25T15:22:11" orderID="123456780000">
<DocumentReference payloadID="5678-4567"/>
</OrderReference>
<ConfirmationItem quantity="1" lineNumber="1">
<ConfirmationStatus quantity="1" type="detail">
<ItemIn quantity="1">
<ItemID>
<SupplierPartID>R954-89</SupplierPartID>
</ItemID>
<ItemDetail>
<UnitPrice>
<Money currency="USD">0.00</Money>
</UnitPrice>
<Description>Test Descritpion 1</Description>
<UnitOfMeasure>QT</UnitOfMeasure>
</ItemDetail>
</ItemIn>
</ConfirmationStatus>
</ConfirmationItem>
<ConfirmationItem quantity="1" lineNumber="2">
<ConfirmationStatus quantity="1" type="detail">
<ItemIn quantity="1">
<ItemID>
<SupplierPartID>Y954-89</SupplierPartID>
</ItemID>
<ItemDetail>
<UnitPrice>
<Money currency="USD">0.00</Money>
</UnitPrice>
<Description>Test Descritpion 2</Description>
<UnitOfMeasure>QT</UnitOfMeasure>
</ItemDetail>
</ItemIn>
</ConfirmationStatus>
</ConfirmationItem>
</ConfirmationRequest>
</Request>
</cXML>
I want to get the value of the payloadID on the DocumentReference element. This is what I have tried so far:
BEGIN
Declare #Xml xml
Set #Xml = ('..The XML From Above..' as xml)
END
--no value comes back
Select c.value('(/*/DocumentReference/#payloadID)[0]','nvarchar(max)') from #Xml.nodes('//cXML') x(c)
--no value comes back
Select c.value('#payloadID','nvarchar(max)') from #Xml.nodes('/cXML/*/DocumentReference') x(c)
--check if element exists and it does
Select #Xml.exist('//DocumentReference');
I tried this in an xPath editor: //DocumentReference/#payloadID
This does work, but I am not sure what the equivalent syntax is in SQL
Calling .nodes() (like suggested in comment) is an unecessary overhead...
Better try it like this:
SELECT #XML.value('(//DocumentReference/#payloadID)[1]','nvarchar(max)')
And be aware, that XPath starts counting at 1. Your example with [0] cannot work...
--no value comes back
Select c.value('(/*/DocumentReference/#payloadID)[0]','nvarchar(max)') from...
I am trying to group some elements together under one node. This is my current SQL;
declare #xml xml
set #xml = (
select (
select
'DERIVED' '#type',
m.NuixDerivedFieldName '#name', (
SELECT
NuixFieldType as 'metadata/#type',
NuixFieldName as 'metadata/#name'
from eddsdbo.MetadataMapping m1
where m1.NuixDerivedFieldName = m.NuixDerivedFieldName
for xml path ('first-non-blank'), type
)
from (select distinct NuixDerivedFieldName from eddsdbo.MetadataMapping) m
for xml path ('metadata'))
)
;WITH XMLNAMESPACES(DEFAULT 'http://nuix.com/fbi/metadata-profile')
select #xml for XML PATH ('metadata-list'), ROOT ('metadata-profile')
Which gives me the following output;
<metadata-profile xmlns="http://nuix.com/fbi/metadata-profile">
<metadata-list>
<metadata type="DERIVED" name="Barcode" xmlns="">
<first-non-blank>
<metadata type="CUSTOM" name="Barcode" />
</first-non-blank>
<first-non-blank>
<metadata type="EVIDENCE" name="Barcode" />
</first-non-blank>
</metadata>
I want to group together elements together which have the same 'name' attribute of the metadata element under the <first-non-blank> element.
The desired output should be;
<metadata-profile xmlns="http://nuix.com/fbi/metadata-profile">
<metadata-list>
<metadata type="DERIVED" name="Barcode" xmlns="">
<first-non-blank>
<metadata type="CUSTOM" name="Barcode" />
<metadata type="EVIDENCE" name="Barcode" />
</first-non-blank>
</metadata>
...
My database looks something like this;
NuixFieldName NuixFieldType NuixDerivedFieldName
------------------------------ ------------------------------ ------------------------------
_EmailEntryID PROPERTY EmailEntryID
Audited Audited Audited
Author PROPERTY Author
Barcode CUSTOM Barcode
Barcode EVIDENCE Barcode
I would also like to remove the xlmns namespace identifier from the metadata elements.
Thanks in advance!
You could try this
DECLARE #SampleData AS TABLE
(
NuixFieldName varchar(20),
NuixFieldType varchar(20),
NuixDerivedFieldName varchar(20)
)
INSERT INTO #SampleData
VALUES
('_EmailEntryID','PROPERTY','EmailEntryID'),
('Audited', 'Audited ','Audited'),
('Author ', 'PROPERTY','Author '),
('Barcode', 'CUSTOM ','Barcode'),
('Barcode', 'EVIDENCE','Barcode')
DECLARE #xml XML
SET #xml = (
SELECT
-- sd.NuixDerivedFieldName AS [#name],
'DERIVED' AS [#type],
sd.NuixDerivedFieldName AS [#name],
(
SELECT
sd2.NuixFieldType as '#type',
sd2.NuixFieldName as '#name'
FROM #SampleData sd2 WHERE sd2.NuixDerivedFieldName = sd.NuixDerivedFieldName
FOR XML PATH ('metadata'),ROOT('first-non-blank'), TYPE
)
FROM (select DISTINCT sd.NuixDerivedFieldName from #SampleData sd ) sd
FOR XML PATH('metadata'), ROOT('metadata-list'),TYPE
)
;WITH XMLNAMESPACES(DEFAULT 'http://nuix.com/fbi/metadata-profile')
SELECT #xml FOR XML PATH (''),ROOT('metadata-profile')
return:
<metadata-profile xmlns="http://nuix.com/fbi/metadata-profile">
<metadata-list>
<metadata type="DERIVED" name="Audited">
<first-non-blank>
<metadata type="Audited " name="Audited" />
</first-non-blank>
</metadata>
<metadata type="DERIVED" name="Author ">
<first-non-blank>
<metadata type="PROPERTY" name="Author " />
</first-non-blank>
</metadata>
<metadata type="DERIVED" name="Barcode">
<first-non-blank>
<metadata type="CUSTOM " name="Barcode" />
<metadata type="EVIDENCE" name="Barcode" />
</first-non-blank>
</metadata>
<metadata type="DERIVED" name="EmailEntryID">
<first-non-blank>
<metadata type="PROPERTY" name="_EmailEntryID" />
</first-non-blank>
</metadata>
</metadata-list>
</metadata-profile>
I want to query data from XML. I have managed to retrive data from another set of XML data but this are a bit problematic.
Bellow you see the data and the query that does not retrive any data.
DECLARE #xml XML
SET #xml=N'<DocumentXML>
<LoadApplicationResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Reaktor.Applikator.DTO">
<Application>
<EmbeddedProductList>
<EmbeddedProduct>
<Flag>false</Flag>
<CustomData>
<root xmlns="">
<Guaranteer ChangeTime="2012-04-28T08:50:07.5706054+02:00" ChangedBy="sven" OldValue="">
<Text>4</Text>
</Guaranteer>
<PercentGuarantee ChangeTime="2012-04-28T08:50:07.5706054+02:00" ChangedBy="sven" OldValue="">
<Number>100</Number>
</PercentGuarantee>
</root>
</CustomData>
<DataChangeTime>2014-04-28T08:50:07.5706054+02:00</DataChangeTime>
<ID>12</ID>
<FinanceSeparately>false</FinanceSeparately>
<Guid>5349efcd-457c-4423-b4bb-a28f97dd5e64</Guid>
<PluginData i:nil="true" />
<PriceCalcTime>2014-04-28T08:50:09.2580946+02:00</PriceCalcTime>
<Data>
<root xmlns="">
<root TableId="192">
<Generic.TypeCode>abba</Generic.TypeCode>
</root>
</root>
</Data>
</EmbeddedProduct>
<EmbeddedProduct>
<Flag>false</Flag>
<CustomData i:nil="true" />
<DataChangeTime>1954-10-03T00:00:00</DataChangeTime>
<ID>30</ID>
<FinanceSeparately>false</FinanceSeparately>
<Guid>d587b9b4-94df-4d9b-ba0d-2fdc62823a17</Guid>
<PluginData i:nil="true" />
<PriceCalcTime>2014-04-28T08:49:55.8831802+02:00</PriceCalcTime>
<Data>
<root xmlns="">
<root TableId="013">
<EmbProd.CMSPrice>0</EmbProd.CMSPrice>
<EmbProd.MonthFee Operator="DBLMUL" Target="CUSTOM.EPTermFee.ADD" Source="XPATH://PaySeries[1]/TermLength" DFValue="200">200</EmbProd.MonthFee>
</root>
<root TableId="759" GroupText="210" GroupText0="210">
<Flag>ink</Flag>
<Generic.TypeCode>fil</Generic.TypeCode>
</root>
</root>
</Data>
</EmbeddedProduct>
<EmbeddedProduct>
<Flag>false</Flag>
<CustomData>
<root xmlns="" />
</CustomData>
<DataChangeTime>2012-04-26T14:41:26.4232222+02:00</DataChangeTime>
<ID>16</ID>
<FinanceSeparately>false</FinanceSeparately>
<Guid>c2e2343f-a5d6-43c8-aa18-c43419d20165</Guid>
<PluginData i:nil="true" />
<PriceCalcTime>2014-04-28T08:49:55.8831802+02:00</PriceCalcTime>
<Data>
<root xmlns="">
<root TableId="102">
<EmbProd.MonthFee Operator="DBLMUL" Target="CUSTOM.EPTermFee.ADD" Source="XPATH://PaySeries[1]/TermLength" DFValue="300">300</EmbProd.MonthFee>
<EP.GenericCost Target="COST">114</EP.GenericCost>
</root>
<root TableId="102" GroupText="11" GroupText0="7">
<EP.TermCount Target="DBLMUL">13</EP.TermCount>
</root>
<root TableId="102" GroupText="210" GroupText0="210">
<Generic.TypeCode>frodinge</Generic.TypeCode>
</root>
</root>
</Data>
</EmbeddedProduct>
</EmbeddedProductList>
</Application>
</LoadApplicationResult>
</DocumentXML>'
SELECT tab.col.value('(Flag)[1]', 'nvarchar(max)') AS Flag
,tab.col.value('(Data/root/EmbProd.MonthFee)[1]', 'nvarchar(max)') AS Value
,tab.col.value('(ID)[1]', 'nvarchar(max)') AS Product
FROM #xml.nodes('/DocumentXML//LoadApplicationResult/Application/EmbeddedProductList/EmbeddedProduct') AS Tab(col)
The expected output should look like this:
+-------+-------+---------+
| Flag | Value | Product |
+-------+-------+---------+
| false | | 12 |
| false | 200 | 30 |
| true | 300 | 16 |
+-------+-------+---------+
You need to specify namespace
WITH XMLNAMESPACES ( 'http://schemas.datacontract.org/2004/07/Reaktor.Applikator.DTO' as x)
SELECT tab.col.value('(x:Flag)[1]', 'nvarchar(max)') AS Flag
,tab.col.value('(x:Data/root/root/EmbProd.MonthFee)[1]', 'nvarchar(max)') AS Value
,tab.col.value('(x:ID)[1]', 'nvarchar(max)') AS Product
FROM #xml.nodes('DocumentXML/x:LoadApplicationResult/x:Application/x:EmbeddedProductList/x:EmbeddedProduct') AS Tab(col);
I am not able to retrieve unique list by applying Muenchian method. I am trying to group based on "Series Title" attribute
Sample Input XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Distribution>
<ManifestHeader>
<Assets>
<Asset>
<ID>23341528</ID>
<CreateDate>2008-01-14T17:02:01Z</CreateDate>
<MetaDatas>
<MetaData Name="psa.orig.source.showTitle">Green Home 2008</MetaData>
<MetaData Name="displayRunTime">00:01</MetaData>
<MetaData Name="Series Title">Desperate Landscapes</MetaData>
</MetaDatas>
</Asset>
<Asset>
<ID>23341529</ID>
<CreateDate>2010-08-23T15:44:58Z</CreateDate>
<MetaDatas>
<MetaData Name="psa.orig.source.showTitle">Urban Oasis 2010</MetaData>
<MetaData Name="displayRunTime">00:02</MetaData>
<MetaData Name="Series Title">Toy Hunter</MetaData>
</MetaDatas>
</Asset>
<Asset>
<ID>23377202</ID>
<CreateDate>2007-05-18T07:40:25Z</CreateDate>
<MetaDatas>
<MetaData Name="webSeries"/>
<MetaData Name="psa.orig.source.showTitle">Cool Tools</MetaData>
<MetaData Name="displayRunTime">00:20</MetaData>
<MetaData Name="Series Title">Desperate Landscapes</MetaData>
</MetaDatas>
</Asset>
</Assets>
</ManifestHeader>
</Distribution>
XLST:
<xsl:key name="keySeriesName" match="MetaData[#Name='Series Title']" use="text()" />
<xsl:for-each select="MetaData[#Name='Series Title'][generate-id() =
generate-id(key('keySeriesName', text())[1])]">
also tried:
<xsl:for-each select="MetaData[#Name='Series Title'][count(. | key('keySeriesName',text())[1]) = 1]">
anyhelp would be appreciated
Thanks in advance
Since the <MetaData> elements are children of <MetaData> and you are trying to search across the entire collection of them within the document, you are going to need to adjust your XPath to ensure that you are addressing all of them:
/Distribution/ManifestHeader/Assets/Asset/MetaDatas/MetaData
[#Name='Series Title'][generate-id() =
generate-id(key('keySeriesName', text())[1])]
or you could use the shorter, but less efficient:
//MetaData[#Name='Series Title'][generate-id() =
generate-id(key('keySeriesName', text())[1])]