how to use following xml query with out prefix - sql

In following link
https://msdn.microsoft.com/en-us/library/ms175178.aspx
i found this cote "This prefix is then used in the query body instead of the namespace URI"
This makes me fell that if i do not specify prefix then i have to use uri in place of prefix. So please give me an example of using uri in place of prefix,
because in above link it is not given. only they given example of with prefix.
yours sincerley

This question is not a good question: Please read How to ask a good SQL question and How to create a MCVE
But I'll try to answer it...
A namespace is meant to separate identically named elements. Very often XML fragments are just glued together. It is very likely, that different elements with the same name get together. By using a namespace the combination of namespace and element name is used to identify the element. But it is not important, which alias is used to point to the namespace!
You must distinguish between the "namespace" and the given "alias".
The following example has the element <a> in two flavours. Check this out:
DECLARE #xml XML=
N'<root xmlns="DefaultNS" xmlns:dns="DerivedNS">
<a>This is default</a>
<dns:a>This is derived</dns:a>
</root>';
--no result
SELECT a.value(N'(text())[1]',N'nvarchar(max)')
FROM #xml.nodes(N'/root/a') AS A(a);
--wildcard-namespace: Everything
SELECT a.value(N'(text())[1]',N'nvarchar(max)')
FROM #xml.nodes(N'/*:root/*:a') AS A(a);
--Only default namespace declared: Only default element returned
WITH XMLNAMESPACES(DEFAULT 'DefaultNS')
SELECT a.value(N'(text())[1]',N'nvarchar(max)')
FROM #xml.nodes(N'/root/a') AS A(a);
--.nodes() calls for the derived namespace: Only derived element returned
WITH XMLNAMESPACES(DEFAULT 'DefaultNS'
,'DerivedNS' AS xyz) --Other prefix, doesn't matter
SELECT a.value(N'(text())[1]',N'nvarchar(max)')
FROM #xml.nodes(N'/root/xyz:a') AS A(a); --prefix "dns" would not work, the alias is now "xyz"
--Here I use random prefixes. I took "dns" as alias for the default!
WITH XMLNAMESPACES('DefaultNS' AS dns
,'DerivedNS' AS dns2) --random prefixes for the namespaces, took even dns for the wrong one!
SELECT a.value(N'(text())[1]',N'nvarchar(max)')
FROM #xml.nodes(N'/dns:root/dns:a') AS A(a); --prefix "dns" returns the default ns now! And you need the prefix at `root` too!
--With inline declaration
SELECT a.value(N'(text())[1]',N'nvarchar(max)')
FROM #xml.nodes(N'declare namespace x="DefaultNS"; /x:root/x:a') AS A(a); --The alias "x" is now bound to the default namespace!

Related

How to reach second prefix in xml using posgresSQL

the problem is that I need to extract data from xml, I know how to extract them, but I can't pass prefixes, maybe you can help
<ns2:PositiveInfo xmlns:ns2="http://ws.nGCR">
<BatchResponse xmlns="http://katana">
<Header>
<BatchId>11480644</BatchId>
<State>Finished</State>
<BeginTimeStamp>2022-09-10T10:21:48Z</BeginTimeStamp>
<TimeStamp>2022-09-10T10:21:50Z</TimeStamp>
<FinishTimeStamp>2022-09-10T10:21:50Z</FinishTimeStamp>
<Duration>2.3571</Duration>
<Identifier>600e19f5cc5b4707944b126cc8f6103a</Identifier>
<Subscriber>2810192</Subscriber>
.....
Now im in PositiveInfo prefix, how to reach BatchResponse prefix?
until now I have this query :
select *
from(
select unnest(xpath('/responseContainer/ns2:Report/ns2:Registers/ns2:PositiveInfo',
response_body::XML,
array[array['ns2','http://ws.nGCR']]))::XML as test
from stage_lt.cb_data_execution_entry_details deed
where id = 178752351)xx
To select the BatchResponse element, whose name is in the http://katana namespace, you'll need to bind another prefix (e.g. katana) to the namespace URI http://katana, just as you have bound the ns2 prefix to the namespace URI http://ws.nGCR, then you can use katana: as a namespace prefix in your XPath expression, e.g. /responseContainer/ns2:Report/ns2:Registers/ns2:PositiveInfo/katana:BatchResponse

SPARQL 1.0 - how to apply EXSLT functions in Mulgara

I would like to query a Fedora 3.8.1-based Mulgara triple store and apply an EXSLT string function to the results. The Mulgara documentation[1,2] suggests that the EXSLT[3] functions are builtin, but I'm not sure about the required syntax for accessing them. I've tried declaring the EXSLT namespace as a PREFIX, using the default QName representation, as well as using the full namespace as a URI. The following query is as close as I've been able to get, but it only returns false.
Any advice or suggestions would be greatly appreciated. Thanks for your help.
PREFIX fedora-view: <info:fedora/fedora-system:def/view#>
PREFIX exsl-str: <http://exslt.org/strings>
SELECT ?distincts
FROM <#ri>
WHERE {
?pid fedora-view:disseminates ?dsids .
LET ( ?distincts := str:replace(str(?dsids), "^(info:fedora).*$", "$1"))
}
In this contrived example, the returns would look like:
info:fedora
info:fedora
info:fedora
instead of:
info:fedora/pid:1/TN
info:fedora/pid:35/TECHMD
info:fedora/pid:46/RELS-EXT
[1] https://code.mulgara.org/projects/mulgara/wiki/Functions
[2] https://code.mulgara.org/projects/mulgara/wiki/SPARQLExt
[3] http://exslt.org/

Find XML tag which is present several times

I am working with an Oracle database 19c.
I have a table with the blob field "MSG_BODY". This field contains XML's like that:
<Body xmlns = "http://www.finnova.ch/ZV/EHF/021">
<Auftrag>
<Auftragsinformation>
<Auftragsidentifikation>
<AUF_LNR>987987987987</AUF_LNR>
<APPL_ID>9999</APPL_ID>
</Auftragsidentifikation>
<Auftragsreferenz>
<EXT_REF>TEST-2020082109574181</EXT_REF>
<EXT_AUF_REF>BA18081508D86B28</EXT_AUF_REF>
<KD_LNR_ERF>901</KD_LNR_ERF>
</Auftragsreferenz>
</Auftragsinformation>
<Zahlungsliste>
<Zahlung>
<Identifikation>
<ZV_ZLG_SYS_LNR>987987987987</ZV_ZLG_SYS_LNR>
<ZV_ZLG_LNR>1</ZV_ZLG_LNR>
</Identifikation>
<Referenz>
<EXT_REF>ABCD654654654</EXT_REF>
<EXT_REF_AUF>XX-XXX 230/99999/1</EXT_REF_AUF>
<EXT_REF_AUF_IB>BA9999988888</EXT_REF_AUF_IB>
<ZLG_INSTR_ID>BA999988886666</ZLG_INSTR_ID>
<MeldungsRef>
<MSG_TX_ID>123123123123</MSG_TX_ID>
<CS_ZLG_TRACK_ID>d8047b9f-a8c7-4d74-b5c7-470510240b60</CS_ZLG_TRACK_ID>
<CS_SWIFTGPI_SVC_ID>001</CS_SWIFTGPI_SVC_ID>
</MeldungsRef>
<MeldungsRef>
<MSG_TX_ID_DECK>xxxxxxxxxx</MSG_TX_ID_DECK>
</MeldungsRef>
</Referenz>
<Mitteilung>
<MIT_BEGxxx</MIT_BEG>
<MIT_BEG_XML>
<Ustrd>xxx</Ustrd>
</MIT_BEG_XML>
<PURP_CD>SALA</PURP_CD>
</Mitteilung>
</Zahlung>
</Zahlungsliste>
</Auftrag>
The tag "Zahlung" can exist multiple times and that's OK, but into the the tag "Zahlung" is the
tag "MeldungsRef". This tag should exist zero or one time for every tag "Zahlung". That's a fault shown in the XML above. I now need a query to select all rows in the table, which contains an XML, where the tag "MeldungsRef" is multiple times there. How can I do that?
Thanks for helping me!
Regards,
mablaser
You're looking for a second appearance of the MeldungsRef node within a Zahlung node, so you can look directly for that. This query shows you the first and second instances of the node, using xmlquery() and specifying the appearance to find with [1] or [2]:
select id,
xmlquery(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[1]'
passing xmltype(msg_body)
returning content
) as first,
xmlquery(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[2]'
passing xmltype(msg_body)
returning content
) as second
from your_table;
You could look for the second being not-null, but it's easier to use the same XPath with xmlexists() to test whether a second child node exists:
select id
from your_table
where xmlexists(
'declare default element namespace "http://www.finnova.ch/ZV/EHF/021"; (: :)
/Body/Auftrag/Zahlungsliste/Zahlung/Referenz/MeldungsRef[2]'
passing xmltype(msg_body)
);
db<>fiddle with one good (single node) and one bad (multiple node) row.
i receive the following error: ORA-32512: type 'xquery external variable'
As your base column is a BLOB you need to tell it which character set it's it, e.g.:
passing xmltype(msg_body, nls_charset_id('UTF8'))
db<>fiddle.

Select values from XML with multiple namespaces

I need to read a value of an attribute from an XML column. The data is an XML with multiple namespaces declared:
<sd:objectData xmlns:sd="http://sd-uri">
<sd:object sourceKey="FC5A0A51-7FB6-4C64-A13E-D4B00649E80E">
<do:properties xmlns:do="http://do-uri">
<do:property name="DECISION">
<do:propertyValues clearExistingValues="true">
<do:propertyValue action="add" valueInteger="1000142" tag="Approve" />
</do:propertyValues>
</do:property>
</do:properties>
</sd:object>
</sd:objectData>
I want to read the value of valueInteger, namely in this example 1000142. I tried with WITH XMLNAMESPACES() but I am not able to get it together to define both aliases.
Does this work for you?
DECLARE #XML xml = '
<sd:objectData xmlns:sd="http://sd-uri">
<sd:object sourceKey="FC5A0A51-7FB6-4C64-A13E-D4B00649E80E">
<do:properties xmlns:do="http://do-uri">
<do:property name="DECISION">
<do:propertyValues clearExistingValues="true">
<do:propertyValue action="add" valueInteger="1000142" tag="Approve" />
</do:propertyValues>
</do:property>
</do:properties>
</sd:object>
</sd:objectData>';
WITH XMLNAMESPACES ('http://sd-uri' AS sd,
'http://do-uri' AS do)
SELECT #XML.value('(/sd:objectData/sd:object/do:properties/do:property/do:propertyValues/do:propertyValue/#valueInteger)[1]','int') AS valueInteger;
In addition to Larnu's answer (which is the best and correct answer) just some alternative shortcuts, if you just want to get one value:
This query fetches the needed value in four different approaches
SELECT #XML.value(N'(//*/#valueInteger)[1]',N'int') AS Super_easy_with_double_wildcard
,#XML.value(N'(//*:propertyValue/#valueInteger)[1]',N'int') AS Easy_with_namespace_wildcard
,#XML.value(N'declare namespace do="http://do-uri";
(//do:propertyValue/#valueInteger)[1]',N'int') AS with_local_declaration
,#XML.value(N'declare namespace do="http://do-uri";
declare namespace sd="http://sd-uri";
(/sd:objectData/sd:object/do:properties/do:property/do:propertyValues/do:propertyValue/#valueInteger)[1]',N'int') AS with_full_local_declaration;
The general advise is: Be as specific as possible to avoid hassels. If you do no bother and you just need a readable, quick catch, you can take one of the alternatives.
UPDATE Add a predicate
With a predicate you can place a filter:
SELECT #XML.value(N'(//*:property[#name="DECISION"]//*:propertyValue/#valueInteger)[1]',N'int') AS Example_with_predicate

Parsing XML with namespaces in SQL Server

I am having a hard time trying to parse an XML that has some namespaces defined:
<TravelItineraryReadRS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="2.2.0">
<TravelItinerary xmlns="http://webservices.sabre.com/sabreXML/2011/10">
<CustomerInfo>
<PersonName WithInfant="false" NameNumber="01.01" RPH="1">
<GivenName>JEFF S</GivenName>"
The XMl is stored in an XML type column named response, and I want to get the GivenName value, for which I use the below query:
;WITH XMLNAMESPACES (DEFAULT 'http://webservices.sabre.com/sabreXML/2011/10')
select
response.value('(/TravelItineraryReadRS/TravelItinerary/CustomerInfo/PersonName[1]/GivenName)[1]', 'nvarchar(50)') AS Name
from dbo.RezMonitorXMLdataTest where locator = 'GUBXRV'
but instead of getting JEFF S as a result I get NULL. I think this might be related to the namespaces used. Does anyone know how could I get the GivenName value?
Thanks in advance,
Guzmán
Since your top-level node <TravelItineraryReadRS> is not part of that XML namespace, you cannot use the DEFAULT qualifier. Instead, you have to define a XML namespace prefix, and include that in your XQuery:
;WITH XMLNAMESPACES ('http://webservices.sabre.com/sabreXML/2011/10' AS ns)
SELECT
XmLContent.value('(/TravelItineraryReadRS/ns:TravelItinerary/ns:CustomerInfo/ns:PersonName[1]/ns:GivenName)[1]', 'nvarchar(50)') AS Name
FROM
dbo.RezMonitorXMLdataTest
WHERE
locator = 'GUBXRV'