exctractvalue from xmltype / soap oracle - sql

i need to get "ineedthis" value from field
REQUEST_INFO:
...
<s:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<X-dynaTrace xmlns="http://ns.dynatrace.com/wcf" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">FW3;-1003312095;1;-56375709;115092;0;975784079;78</X-dynaTrace>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<storeContract xmlns="xxx/integration">
<storeRequest>
<contract>
<contractSeries>ineedthis</contractSeries>
select extractvalue(XMLType(sap.REQUEST_INFO),'s/s/storeContract/storeRequest/contract/contractSeries')
from sap
cant get the value

You're trying to extract the path
s/s/storeContract/storeRequest/contract/contractSeries
but your SOAP response doesn't have any nodes called s; it has nodes called Envelope, Header and Body in the namespace s. So you potentially want the path:
/s:Envelope/s:Body/storeContract/storeRequest/contract/contractSeries
which on its own gets an LPX-00601: Invalid token error because it doesn't know what s: is. You can supply the namespaces with the third argument:
select extractvalue(XMLType(sap.request_info),
'/s:Envelope/s:Body/storeContract/storeRequest/contract/contractSeries',
'xmlns="xxx/integration" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"'
) as contractseries
from sap;
or the lazy way is to wildcard the namespace and only identify the final node you want:
select extractvalue(XMLType(sap.request_info),'//*:contractSeries') as contractseries
from sap;
But extractvaue is deprecated so it's better to use XMLQuery - still being lazy:
select XMLQuery('//*:contractSeries/text()'
passing XMLType(sap.request_info)
returning content) as contractseries
from sap;
or with explicit namespaces:
select XMLQuery('
declare default element namespace "xxx/integration";
declare namespace s="http://schemas.xmlsoap.org/soap/envelope/";
/s:Envelope/s:Body/storeContract/storeRequest/contract/contractSeries/text()'
passing XMLType(sap.request_info)
returning content) as contractseries
from sap;
CONTRACTSERIES
------------------------------
ineedthis
db<>fiddle

Related

How to combine value from XML with a String?

I have a listener that receives a XML payload. In the following transform I would like to combine a string and a value this XML, but it breaks
This is the XML I receive:
<?xml version="1.0" encoding="UTF-8"?>
<INVOIC02>
<IDOC BEGIN="1">
<RESULT>12345</RESULT>
</IDOC>
</INVOIC02>
This is my transformation:
%dw 2.0
output text/plain
---
"Result:" ++ (payload.INVOICE.IDOC.RESULT)
Apparently I access the payload wrong, I guess. The error message looks like this:
You called the function 'Value Selector' with these arguments:
1: String ("\n\n ...)
2: Name ("INVOICE")
But it expects one of these combinations:
(Array, Name)
...
Any idea what I'm doing wrong?
The problem is that the xml doesn't have the mimetype set. As a workaround set the payload with value payload and set also the mimetype to xml

XPath failing for namespaced XML via SQL EXTRACTVALUE?

I have am trying to parse FaultMessage from an XML response using EXTRACTVALUE. Below is my SQL code:
SELECT EXTRACTVALUE( XMLTYPE('
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring xml:lang="tr-TR">İstek şeması doğrulanamadı. Lütfen tüm bilgileri kontrol edin.</faultstring>
<detail>
<Fault xmlns="http://schemas.datacontract.org/2004/07/CustomServiceLibrary.DataContract" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<FaultCode>Schema_Customer_005|1e8c66-c333-4357-9c7d-3f4fcd553</FaultCode>
<FaulCategory>Schema</FaulCategory>
<FaultMessage> Customer name can not be blank, can not contain spaces, or any special characters. LASTNAMEFIRSTNAME is the required format. </FaultMessage>
<FaultDetailedMessage>UMUT DEMIRCI</FaultDetailedMessage>
</Fault>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>'),
'/s:Envelope/s:Body/s:Fault/detail/*:Fault/FaultMessage',
'xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://schemas.datacontract.org/2004/07/CustomServiceLibrary.DataContract" ') a
FROM DUAL
Please suggest how I can get FaultMessage.
Given:
The deeper Fault element and its descendents are in the http://schemas.datacontract.org/2004/07/CustomServiceLibrary.DataContract namespace.
You appear to have already defined the a namespace prefix for http://schemas.datacontract.org/2004/07/CustomServiceLibrary.DataContract
Using * as a wildcard for a namespace prefix requires XPath 2.0+.
Change
/s:Envelope/s:Body/s:Fault/detail/*:Fault/FaultMessage
to
/s:Envelope/s:Body/s:Fault/detail/a:Fault/a:FaultMessage
so that your XPath will be correct and not require an XPath 2.0+ processor.

How to generate namespaces in XML docs with Db2?

I want to generate the following xml doc in db2 and it has several namespaces:
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
xmlns:ComIbmCompute.msgnode="ComIbmCompute.msgnode"
xmlns:ComIbmDatabase.msgnode="ComIbmDatabase.msgnode"
xmlns:ComIbmWSInput.msgnode="ComIbmWSInput.msgnode"
xmlns:ComIbmWSReply.msgnode="ComIbmWSReply.msgnode"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
xmlns:eflow="http://www.ibm.com/wbi/2005/eflow"
xmlns:utility="http://www.ibm.com/wbi/2005/eflow_utility"
nsURI="myflow/FIPRRCV.msgflow" nsPrefix="myflow_FIPRRCV.msgflow">
This does not work:
`SELECT XMLELEMENT(NAME "ecore:EPackage",
XMLNAMESPACES('eclipse.org/emf/2002/Ecore'; AS "ecore")) as "result"
FROM SYSIBM.SYSDUMMY1 WITH UR;`
How can I define multiple namespaces and use them in elements and attributes?
The function to use is called XMLNAMESPACES. The name suggests it is not a single, but multiple namespaceS are possible. :)
You can provide several namespace declarations in a comma-separated list. Only one namespace can be set as default namespace. Try something like this:
SELECT XMLELEMENT(NAME "ecore:EPackage",
XMLNAMESPACES('eclipse.org/emf/2002/Ecore' AS "ecore",
'example.com/foobar' as "foobar")) as "result"
FROM SYSIBM.SYSDUMMY1
If you need to add attributes with a prefix in their name, then just pass that combined string as attribute name to XMLATTRIBUTES. The xmi:version="2.0" in your example is "xmi:version" as name with a value of 2.0.

How to retrive value from soap response jmeter

I have this soap response and i need to get the value of the tag platformMessage i writed a xpath query but it doesnt work, checking the log file in jmeter in tells me this "Prefix must resolve to a namespace: ns2", heres the xpath query
/S:Envelope[#xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"]/S:Body/ns2:activateProductResponse[#xmlns:ns2="http://ws.business.api.fulfillmentengine.com/"]/return/platformMessage
heres the xml
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:activateProductResponse xmlns:ns2="http://ws.business.api.fulfillmentengine.millicom.com/">
<return>
<platformCode>1</platformCode>
<platformMessage>Fail operation.El set-top box ya existe. Code Response:|22098: 22098: 1</platformMessage>
<responseCode>13</responseCode>
<responseMessage>Error executing action in platforn</responseMessage>
<UUID>3cb49b29-513e-11e6-b5db-005056807f0c</UUID>
<platformName>INTRAWAY</platformName>
</return>
</ns2:activateProductResponse>
</S:Body>
</S:Envelope>
Using #xmlns:ns2 in the xpath is not valid because despite appearances a namespace is not the same as an attribute.
If you enable "use namespaces", then the following xpath should work:
/S:Envelope/S:Body/ns2:activateProductResponse/return/platformMessage
Or if you want a dirty (and slow) workaround, you can reference the node names like so:
/*[local-name()='Envelope']/*[local-name()='Body']/*/[local-name()='activateProductResponse]/return/platformMessage
you should read:
https://jmeter.apache.org/usermanual/component_reference.html#XPath_Extractor
https://jmeter.apache.org/usermanual/component_reference.html#XPath_Assertion
pay particular attention to:
As a work-round for namespace limitations of the Xalan XPath parser implementation on which JMeter is based, you can provide a Properties file which contains mappings for the namespace prefixes:
prefix1=Full Namespace 1
prefix2=Full Namespace 2
…
You reference this file in jmeter.properties file using the property:
xpath.namespace.config
Look in jmeter.properties for this property and everything is explained clearly

SQL Server Grabbing Value from XML parameter to use in later query

I am really new to SQL Server and stored procedures to begin with. I need to be able to parse an incoming XML file for a specific element's value and compare/save it later in the procedure.
I have a few things stacked against me. One the Element I need is buried deeply inside the document. I have had no luck in searching for it by name using methods similar to this:
select CurrentBOD = c.value('(local-name(.))[1]', 'VARCHAR(MAX)'),
c.value('(.)[1]', 'VARCHAR(MAX)') from #xml.nodes('PutMessage/payload/content/AcknowledgePartsOrder/ApplicationArea/BODId') as BODtable(c)
It always returns null.
So, I am trying something similar to this:
declare #BODtable TABLE(FieldName VARCHAR(MAX),
FieldValue VARCHAR(MAX))
SELECT
FieldName = nodes.value('local-name(.)', 'varchar(50)'),
FieldValue = nodes.value('(.)[1]', 'varchar(50)')
FROM
#xml.nodes('//*') AS BODtable(nodes)
declare #CurrentBOD VARCHAR(36)
set #CurrentBOD = ''
SET #CurrentBOD = (SELECT FieldValue from #BODtable WHERE FieldName = 'BODId')
This provides me the list of node names and values correctly (I test this in a query and BODtable has all elements listed with the correct values), but when I set #CurrentBOD it comes up null.
Am I missing an easier way to do this? Am I messing these two approaches up somehow?
Here is a part of the xml I am parsing for reference:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity- secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401- wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<payloadManifest xmlns="???">
<c contentID="Content0" namespaceURI="???" element="AcknowledgePartsOrder" version="4.0" />
</payloadManifest>
<wsa:Action>http://www.starstandards.org/webservices/2005/10/transport/operations/PutMessage</wsa:Action>
<wsa:MessageID>uuid:df8c66af-f364-4b8f-81d8-06150da14428</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>???</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="Timestamp-bd91e76f-c212-4555-9b23-f66f839672bd">
<wsu:Created>2013-01-03T21:52:48Z</wsu:Created>
<wsu:Expires>2013-01-03T21:53:48Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsu="???" wsu:Id="???">
<wsse:Username>???</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">???</wsse:Password>
<wsse:Nonce>???</wsse:Nonce>
<wsu:Created>2013-01-03T21:52:48Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<PutMessage xmlns="??????">
<payload>
<content id="???">
<AcknowledgePartsOrder xmlns="???" xmlns:xsi="???" xsi:schemaLocation="??? ???" revision="???" release="???" environment="???n" lang="en-US" bodVersion="???">
<ApplicationArea>
<Sender>
<Component>???</Component>
<Task>???</Task>
<ReferenceId>???</ReferenceId>
<CreatorNameCode>???</CreatorNameCode>
<SenderNameCode>???</SenderNameCode>
<DealerNumber>???</DealerNumber>
<PartyId>???</PartyId>
<LocationId />
<ServiceId />
</Sender>
<CreationDateTime>2013-01-03T21:52:47</CreationDateTime>
<BODId>71498800-c098-4885-9ddc-f58aae0e5e1a</BODId>
<Destination>
<DestinationNameCode>???</DestinationNameCode>
You need to respect the XML namespaces!
First of all, your target XML node <BODId> is inside the <soap:Envelope> and <soap:Body> tags - both need to be included in your selection.
Secondly, both the <PutMessage> as well as the <AcknowledgePartsOrder> nodes appear to have default XML namespaces (those xmlns=.... without a prefix) - and those must be respected when you select your data using XPath.
So assuming that <PutMessage xmlns="urn:pm"> and <AcknowledgePartsOrder xmlns="urn:apo"> (those are just guesses on my part - replace with the actual XML namespaces that you haven't shown use here), you should be able to use this XPath to get what you're looking for:
;WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS soap,
'urn:pm' AS ns, 'urn:apo' AS apo)
SELECT
XC.value('(apo:BODId)[1]', 'varchar(100)')
FROM
#YourXmlVariable.nodes('/soap:Envelope/soap:Body/ns:PutMessage/ns:payload/ns:content/apo:AcknowledgePartsOrder/apo:ApplicationArea') AS XT(XC)
This does return the expected value (71498800-c098-4885-9ddc-f58aae0e5e1a) in my case.