XML parsing error in SQL Server stored procedure - sql

I want to parse the below XML in a SQL Server stored procedure and update some tables based on this XML. I have implemented the same using OPENXML but now there is one more line added to the beginning of the XML, because of which am getting unexpected errors. Is it possible to somehow skip the first tag alone while parsing
Parsing code :
set #Lead= (select lead
from openxml(#DOCHANDLE,'/DBO.TBLLEADS',2) with (lead INT 'LEAD'))`
XML here:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<LEADS>
<LEAD>6680299</LEAD>
<JOBNO>50919</JOBNO>
<BEGINDATE>4-04-2013</BEGINDATE>
<ENDDATE>04/14/2013</ENDDATE>
</LEADS>

Well, not the most elegant solution, but will get it back to working:
Before you prepare your XML document, run this statement on the variable containing the XML:
SET #XMLVariable = REPLACE(#XMLVariable, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>', '')
Basically you're leveraging the REPLACE function to replace the unnecessary header string with nothing.

Related

Exception cx_st_match_element when deserializing XML?

I'm having trouble getting a simple transformation for XML to work in ABAP. I keep getting the exception cx_st_match_element when I try to execute it on a test XML document inside of a report.
I have the following XML that I want to transform into an ABAP internal table:
<?xml version="1.0" encoding="UTF-8"?>
<studenten xmlns="http://www.foo.be/bar/preinschrijvingsflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.foo.be/bar/preinschrijvingsflow bar_studenten.xsd">
<student>
<barGuid>1</barGuid>
<familienaam>Doe</familienaam>
<voornaam>John</voornaam>
<geslacht>1</geslacht>
<nationaliteit>BE</nationaliteit>
<geboortedatum>1995-11-18</geboortedatum>
<geboorteplaats>Antwerpen</geboorteplaats>
<email>John.Doe#gmail.com</email>
<straatNummer>Grote Markt 1 bus 0102</straatNummer>
<postcode>1000</postcode>
<gemeente>Brussel</gemeente>
<land>BE</land>
<telefoonnummer>+32123456789</telefoonnummer>
<academiejaar>2021</academiejaar>
</student>
</studenten>
To this end I defined the following simple transformation I called zc_tr_student:
<?sap.transform simple?>
<tt:transform
xmlns="http://www.foo.be/bar/preinschrijvingsflow"
xmlns:tt="http://www.sap.com/transformation-templates"
xmlns:ddic=" http://www.sap.com/abapxml/types/dictionary">
<tt:root name="studenten" type="ddic:ZCTT_bar_STUDENT"/>
<tt:template>
<studenten>
<tt:loop ref=".studenten" name="studenten">
<student>
<barGuid tt:value-ref="$studenten.bar_guid"/>
<familienaam tt:value-ref="$studenten.familienaam"/>
<voornaam tt:value-ref="$studenten.voornaam"/>
<geslacht tt:value-ref="$studenten.geslacht"/>
<nationaliteit tt:value-ref="$studenten.nationaliteit"/>
<geboortedatum tt:value-ref="$studenten.geboortedatum"/>
<geboorteplaats tt:value-ref="$studenten.geboorteplaats"/>
<email tt:value-ref="$studenten.email"/>
<straat_nummer tt:value-ref="$studenten.straat_nummer"/>
<postcode tt:value-ref="$studenten.postcode"/>
<gemeente tt:value-ref="$studenten.gemeente"/>
<land tt:value-ref="$studenten.land"/>
<telefoonnummer tt:value-ref="$studenten.telefoonnummer"/>
<academiejaar tt:value-ref="$studenten.academiejaar"/>
</student>
</tt:loop>
</studenten>
</tt:template>
</tt:transform>
In the tt:value-refattributes I refer to the field in the DDIC line type of the ABAP internal table corresponding to the tag in the XML.
If I call this simple transformation from an ABAP report like this:
call transformation zc_tr_student
source xml lv_bxml
result studenten = p_student.
The cx_st_match_element is thrown.
I validated both the syntax of the file and its adherence to the schema. The XML file and the XSD file are present in the same directory on the application server. I have no idea why the ST fails as the cx_st_match_element instance does not have any useful information except that it expected a studenten element. That element is clearly present in the XML file as the root element.
I'm inexperienced with defining simple transformations and I can't spot my error myself. Thank you in advance for your help,
Joshua

Error: XML declaration must be the first node in the document, and no white space characters are allowed to appear before it

The functionality is like, we could write the plane SQL queries in XML and then we could import that xml in Product to see the changes in database.
In Update statement, I need to use the below update query. But getting 'XML declaration must be the first node in the document' error when trying to set column value.
<?xml version="1.0" encoding="utf-8"?>
<Metadata ClientSchemaVersion="1.1" Name="DummyName">
<Differences>
<Updates>
---
---
Begin
Update TABLE_NAME
Set //In next line, error is comming
ColumnName='<?xml version=''1.0'' encoding=''utf-16le'' ?><scenario xmlns='Text'><id>12345</id><title>
--
--
--
WHERE Condition
END
</Differences>
</Metadata>
How I could achieve that use case. Could someone help me out here.
Note- The same Update Query is working fine if ran in SQL Server directly
Two XML declarations (<?xml ... ?>) are not allowed in an XML document. Only one is permitted, and it must be at the very top of the document.
Here are two ways you can repair your XML:
Remove the second XML declaration. The default for that SQL-embedded XML will then be XML version 1.0 with UTF-8 encoding.
If the processing application supports it, wrap the SQL in a CDATA section such that the SQL-embedded XML document is no longer parsed as XML.
<![CDATA[
... SQL with embedded XML that can contain its own XML declaration ...
]]>
See also
Error: The processing instruction target matching "[xX][mM][lL]" is not allowed

How to create a message containing xml prolog declaration

I am trying to create some dynamic xml messages which will be sent to a service which expects xml. Said service also needs the xml prolog to be specified.
As I want to do a lot of manipulation on the xml I am reading it in a native xml type, however it seems that karate loses the xml prolog information during the conversion (on 0.9.5 and 0.9.6.RC3)
Feature: Example
# https://www.w3.org/TR/xml/#sec-prolog-dtd
Scenario: Example
Given def nativeXML =
"""
<?xml version="1.0" encoding="UTF-8" ?>
<greeting>Hello world</greeting>
"""
When string nativeToString = nativeXML
* print nativeToString
Then assert nativeToString.contains("encoding")
Is there a way to preserve the xml prolog?
Code to reproduce this can be found here: https://github.com/KostasKgr/karate-issues/blob/xml_prolog_to_string/src/test/java/examples/example.feature
Kind regards
Right now there is no other way but to append it manually, which IMO is simple enough. Karate removes it by default during a string conversion, because it gets in the way during Node operations.
Given def temp =
"""
<?xml version="1.0" encoding="UTF-8" ?>
<greeting>Hello world</greeting>
"""
* string body = temp
* def body = '<?xml version="1.0" encoding="UTF-8" ?>' + body
* print body
Then assert body.contains("encoding")

Xml node name Parsing using SQL

I need to get the value of the tag "supervisor....." The problem is that those tag name are dynamic, they change for each person. I have tried using Extract value but it works only if you use a static tag name.
It is in Oracle environment.
Thanks for your help.
Ourson
XML Extract
<?xml version="1.0" encoding="UTF-8"?>
<TRANSACTION>
<TransCtx>
<supervisorCalcAttributes classType="Ht">
<SupervisorId10977 classType="s">Matt, Clinton</SupervisorId10977>
<SupervisorId4753 classType="s">Bob, Sponge</SupervisorId4753>
<FND_ENTERPRISE_ID classType="s">1</FND_ENTERPRISE_ID>
</supervisorCalcAttributes>
</TransCtx>
</TRANSACTION>
SQL Query
select
Extractvalue( xmltype('<root>'||txndata.data_cache||'</root>'),
'root/TRANSACTION[1]/TransCtx[1]/supervisorCalcAttributes[1]/**LineItem**[1]' ) as test
from hrc_txn_data txndata, hrc_txn_header txnhe
where txnhe.transaction_id=txndata.transaction_id

How to use <= inside an XML element?

I have a config.xml file that contains a SQL query. The query will end up getting read and performed in c#. However, I need to know how to write the query contained inside the XML element. The problem is that the query uses <= in a WHERE statement. The '<' part of the query causes the XML to think it is supposed to esacpe the element, I think. How can i include this basic select statement in the XML file? I noticed > works fine. Obviously, I could swap the order of the comparison, but I want to know how I can specifically include < please.
<?xml version="1.0" encoding="utf-8" ?>
<root>
<Connections>
<Connection>
<Source>Data Source=XXX-XXX; Initial Catalog=MyData;Integrated Security=True</Source>
<Query>Select * FROM Info WHERE EffectiveDate <= GETDATE() </Query>
</Connection>
</Connections>
</root>
Use a CDATA block. Then you wouldn't have to encode your query.
For example:
<Query><![CDATA[
Select * FROM Info WHERE EffectiveDate <= GETDATE()
]]></Query>
You could encode the < character in the config file < and decode it for use.