Xquery transformation on text data in response - xslt-1.0

I want to get a xquery transformation drafted for below data.. here as part of service response fault, I am getting below payload and need to capture the data in ErrorCode element.
challenge that I am having here is, this is not part of a XML structure, its coming as part of CDATA tags.
Could you please suggest how I can get this value in a variable same.
Say I am getting this structure as part of $Fault and now need to assign ErrorCode in a new variable $FaultCode
$FaultCode = $Fault/con:details/con1:ErrorResponseDetail/con1:detail/ ********
I am not sure how I can capture this further detail element
<con:fault xmlns:con="http://www.bea.com/wli/sb/context">
<con:errorCode>382502</con:errorCode>
<con:reason>eceived an error response</con:reason>
<con:details>
<con1:ErrorResponseDetail xmlns:con1="http://www.bea.com/wli/sb/stages/transform/config">
<con1:detail>
<![CDATA[<Error xmlns="http://servic.abcd.net/V1">
<ErrorCode>DATA_AVAILABILITY</ErrorCode>
<ErrorDescription>{"description":"No Cdata for )"}</ErrorDescription>
</Error>]]></con1:detail>
<con1:http-response-code>404</con1:http-response-code>
</con1:ErrorResponseDetail>
</con:details>
<con:location>
<con:node>TestPPNode</con:node>
<con:pipeline>TestPPNode_request</con:pipeline>
<con:stage>Test Stage</con:stage>
<con:path>request-pipeline</con:path>
</con:location>
</con:fault>

Assuming XQuery 3.1 with the parse-xml function (https://www.w3.org/TR/xpath-functions/#func-parse-xml) you can use
declare namespace con="http://www.bea.com/wli/sb/context";
declare namespace con1="http://www.bea.com/wli/sb/stages/transform/config";
declare namespace V1 = "http://servic.abcd.net/V1";
/con:fault/con:details/con1:ErrorResponseDetail/con1:detail!parse-xml(.)/V1:Error/V1:ErrorCode/data()
to get the string value DATA_AVAILABILITY, see https://xqueryfiddle.liberty-development.net/6qM2e27 for demo.
With XQuery 1 there is not XML parsing which is needed to solve this properly but you can of course try to use string functions to extract the data e.g.
/con:fault/con:details/con1:ErrorResponseDetail/con1:detail/substring-before(substring-after(., '<ErrorCode>'), '</ErrorCode>')

Related

How do i navigate the path of a json object that has namespace prefixes (eg n1:, n7: ) in sql server using OPENJSON?

I want to obtain xml files from an API (I can not get Json formats from this API). Thereafter i want to convert them to JSON and then save then to oneDrive using a logic app. (I intend to create tables from these json files in Azure SQL server)
My approach so far is trigger the logic app with an HTTP GET response.
convert the recieved xml file from step 1 above to json using json(xml(triggerBody())) and save it to oneDrive.
The logic App steps are: 1) GET an HTTP response from the API 2) Save the response as json on oneDrive using the function json(xml(triggerBody()))
here is a copy of the xml file from the API:
<?xml version="1.0" encoding="ISO-8859-1"?>
-<n1:VareResult xmlns:n1="http://ABCC.Schemas.Vare/8.0" xmlns:n7="http://ABCC.Schemas.Common/8.0">
-<n1:Header>
-<n1:EksportType>
<n7:EksportId>0</n7:EksportId>
<n7:Eksportmetode/>
<n7:StartIndex>0</n7:StartIndex>
<n7:BatchSize>2000</n7:BatchSize>
<n7:TotalCount>1</n7:TotalCount>
<n7:VersionNr/>
</n1:EksportType>
-<n1:Result> <n7:ResultValue>Success</n7:ResultValue> </n1:Result>
</n1:Header>
-<n1:VareListe>
-<n1:Vare>
-<n1:Status>
<n7:Created>2004-06-27T15:30:57.549</n7:Created>
<n7:Updated>2019-11-20T09:34:03.008</n7:Updated>
</n1:Status>
<n1:ABCCNr>10203</n1:ABCCNr>
........
........
Here is its corresponding json file:
{"?xml":{"#version":"1.0","#encoding":"iso-8859-1"},"n1:VareResult":
{"#xmlns:n7":"http://ABCC.Schemas.Common/8.0","#xmlns:n1":"http://ABCC.Schemas.Vare/8.0","n1:Header":
{"n1:EksportType":
{"n7:EksportId":"0","n7:Eksportmetode":null,"n7:StartIndex":"0","n7:BatchSize":"2000","n7:TotalCount":
"1","n7:VersionNr":null},"n1:Result":{"n7:ResultValue":"Success"}},"n1:VareListe":{"n1:Vare":
{"n1:Status":{"n7:Created":"2004-06-27T15:30:57.549","n7:Updated":"2019-11-20T09:34:03.008"},
"n1:ABCCNr":"10203",
........
.......
As you see the json file has namespace prefixes too. I am trying to navigate the path in sql server. Here is the example:
Image below shows result from the command: select * FROM OPENJSON(#jsonObject)
I want to access the values for the key n1:VareResult.
I have tried to navigate the path like this: select * FROM OPENJSON (#jsonObject,'$.n1:VareResult' )
But I get the error: "JSON path is not properly formatted. Unexpected character ':' is found at position 4."
Is there an escape sequence that can let me navigate the path even if it has these 'forbidden characters'?
If not is there a way i can control the conversion from xml to json in step 2 above so that the namespace prefixes are omitted for each element?
Let me give you an example for this, then you can try somethins like this:
DECLARE #json NVARCHAR(4000) = N'{
"path": {
"to":{
"sub-object":["en-GB", "en-UK","de-AT","es-AR","sr-Cyrl"]
}
}
}';
SELECT [key], value
FROM OPENJSON(#json,'$.path.to."sub-object"')
Additional reference:
https://learn.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql?view=sql-server-ver15
Hope it helps.
Using the tip from: https://stackoverflow.com/a/45873164/10404094, I added double quotes around the field names in sql server and it worked. Just like this:
select * FROM OPENJSON (#jsonObject, '$."n1:VareResult"."n1:VareListe"."n1:Vare" ')
This fixed my problem! Thanks stackoverflow!

How to read-in a FOR XML call from a Kamiak Query component in Delphi D6?

Performing an SQL FOR XML RAW statement call with a Kamiak ADO Query component in Delphi6. How to read the returned XML back out of that query component in your code?
Initial problems:
1) There is no "field name" to refer to in the Kamiak components "FieldByName()" method.
2) Attempts to reference the query results as Query.Fields.Fields[0] returns binary that the XMLPartner component can't read-in via their LoadFromMemory( ) method call.
The following is a beautifully simple tweak to the FOR XML RAW statement that made it exceptionally easy to read back out the XML result of the SQL call back out of the kamiak ADO Query component in code.
Essentially take the existing FOR XML RAW select statement, and wrap it up inside the following:
SELECT CAST((< your FOR XML RAW select stmt goes here >) AS VARCHAR(MAX)) AS XmlData
Then... within your Delphi code you can just refer to the returned XML as follows:
sXML := MyKamiakQryObject.FieldByName('XmlData').AsString();
Before doing this I was having a bear of a time with trying to extract the XML content of that query.
So I wanted to make sure to share this for the next guy.

XML parsing with namespace SQL Server

We are cleaning up data in our database and a column has XML details inside of it which we want to be able to convert into plain text.
Below is the sample XML in the table column.
<FlowDocument PagePadding="5,5,5,5" Name="RTDocument" AllowDrop="True" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Paragraph>FILE DESTROYED - MAY 21st, 2008</Paragraph>
<Paragraph>todo</Paragraph>
</FlowDocument>
I am using this query, but it is not rendering the desired output due to the presence of Namespace (if I remove the namespace from the XML, I am able to render the output successfully).
SELECT
CAST(CAST(Comments AS XML).query('data(/FlowDocument/Paragraph)') AS VARCHAR(7000)) AS activity
FROM
dbo.Activities
WHERE
ActivityID = 1
Kindly help in this matter.
Thanks
You can also declare your namespace like this:
;WITH xmlnamespaces(DEFAULT 'http://schemas.microsoft.com/winfx/2006/xaml/presentation')
SELECT
CAST(CAST(Comments AS XML).query('data(/FlowDocument/Paragraph)') AS VARCHAR(7000)) AS activity
FROM [dbo].Activities where ActivityID=1
Other options are given here: parsing xml using sql server
You need to use namespace declaration in your Query as per: https://msdn.microsoft.com/en-us/library/ms191474.aspx
so your query portion would look something like:
query('
declare namespace NS="http://schemas.microsoft.com/winfx/2006/xaml/presentation";
data(/NS:FlowDocument/NS:Paragraph)
')

How to Extract the value of resultSet returned from JDBC response (Via MEL) Mule ESB

I have JDBC where I'm calling the stored Procedure, It is returning the response as below, But I'm pretty not sure how to extract the value of result set
Please find the response from DB
{updateCount1=4,resultSet1=[{XML_F5RYI-11YTR=<Customers><Customer1>John<Customer1><Customer2>Ganesh<Customer2><Customers>}],resultSet2[{SequenceNumber=94}],updateCount2=1, updateCount3=4}
I have used the this expression #[message.payload.get(0)], It has return the ResultSet as below, But not exactly value required. I need to take the xml value of XML_F5RYI-11YTR.
{XML_F5RYI-11YTR=<Customers><Customer1>John<Customer1><Customer2>Ganesh<Customer2><Customers>}
Also tried like below
#[message.payload.get(0).XML_F5RYI-11YTR] but getting error , not able to extract the xml.
Could you please suggest how can I extract the xml from the ResultSet1
In most cases, the way you did it should work. I think what is happening here is that the hyphen in the column name is interpreted by the MEL parser as a subtraction. So you could change yours to this syntax, and it should work:
#[message.payload.get(0)['XML_F5RYI-11YTR']]
Also you can omit "message", as payload is resolvable directly:
#[payload.get(0)['XML_F5RYI-11YTR']]
You could use array bracket syntax to access the first row in the result set, instead of the get method:
#[payload[0]['XML_F5RYI-11YTR']]
Finally, you might want to do something for each row returned from the database. If you use a collection-splitter or a for-each, your payload will be the map that represents the row, instead of a list of maps representing the whole result set:
<collection-splitter />
<logger message="#[payload['XML_F5RYI-11YTR']]" />
EDIT
To access the result set in the payload shown in the question, you would need to access it like so:
#[payload.resultSet1[0]['XML_F5RYI-11YTR']]
The database connector gives you a list of maps. The map keys will be the name of the columns. Therefore if you want to get updateCount1, you can use something like this:
#[payload.get('updateCount1')]"
Thump rule - you database connector gives you list of map, not sure what format does it is carry, if you want XML_F5RYI.. value then do the below
[message.payload.get(0)] convert it to json or map from which #[message.payload.get("XML_F5RYI-11YTR")]

Parsing XML Element value entirely in SQL form arbitrary string

We have log/audits we have compiled over some time that we would like to run some brief reports on.
One of the columns in the logs is JSON, but contains XML. We want to be able to parse out the value of a certain XML tag for each of the rows. So given an arbitrary string such as the following:
{ "XmlData" :"<tag1><tag2><TagToParse>234</TagToParse></tag2><tag1>".....}
I would like to run a sql query that return 234 when I give it the tag name TagToParse
What is the easiest way to do this ENTIRELY in SQL?
Give your container will always be tag1, then something like this should do it:
DECLARE #MyXML XML
SET #MyXML = '<tag1><tag2><TagToParse>234</TagToParse></tag2></tag1>'
SELECT
a.b.value('(/tag1//TagToParse/node())[1]', 'nvarchar(max)') AS Tag
FROM #MyXML.nodes('tag1') a(b)
Good luck.