clob to xmltype: converting " to &quote - oracle

I am converting clob to xmltype in plsql as below.
xml xmltype := xmltype(Input);
Input variables contains the text as below
<request xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<comment>Hello, this is "james"</comment>
</request>
After the xmltype conversion the text is changed to Hello, this is "james""
When tried to extract the xml from xmltype I need to extract the text as Hello, this is "james".

Xmlcast
select xmlcast(xmltype('<request xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<comment>Hello, this is "james"</comment>
</request>').extract('/request/comment/text()') as varchar2(100) ) from dual;

just especify the charset like this: XMLTYPE(Input,NLS_CHARSET_ID('AL32UTF8'))

Related

How to return Table as a row using Oracle XML DB Webservices

I am trying to expose an Oracle Table as a web service using XML DB Service.
I want to return multiple rows of table based on where condition passed in the Request of the web service.
Following -: native-oracle-xml-db-web-services-11gr1
A procedure is developed which takes PK column as input, and returns column as output. It works when return is column by column.
But when I try to return the complete row as type, it is not working.
This is working.
URL of webservice -: http://domain:8080/orawsv/TEST/GET_TEST_TAB?wsdl
create or replace PROCEDURE GET_TEST_TAB (
p_id IN test_tab.id%TYPE,
p_description OUT test_tab.description%type) AS
BEGIN
SELECT description into p_description FROM test_tab
WHERE id = p_id;
END GET_TEST_TAB;
Now I want to return the multiple rows of TEST_TAB table, without hard coding the column name.
I have modified the procedure as
CREATE OR replace PROCEDURE P_TableAsWS_XMLIN_XMLOUT (
p_in IN XMLTYPE,
p_out OUT XMLTYPE
) AS
BEGIN
-- cursor_ OUT SYS_REFCURSOR) AS
-- with data as
--(select '<a><c>1</c><c>2</c></a>' xmlval
-- from dual)
SELECT
XMLELEMENT(
"employees",XMLAGG(XMLELEMENT(
"employee",XMLFOREST(e.id AS "empno",e.description AS "ename")
) )
)
INTO p_out
FROM
test_tab e,
XMLTABLE ( '/inp/*' PASSING p_in
COLUMNS
id varchar(50) PATH '/id'
) inp
WHERE
e.id = inp.id ;
end P_TableAsWS_XMLIN_XMLOUT;
Passing Input -:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:p="http://xmlns.oracle.com/orawsv/TEST/P_TABLEASWS_XMLIN_XMLOUT">
<soapenv:Header/>
<soapenv:Body>
<p:P_TABLEASWS_XMLIN_XMLOUTInput>
<p:P_OUT-XMLTYPE-OUT/>
<p:P_IN-XMLTYPE-IN>
<inp>
<id>1</id>
<id>2</id>
</inp>
</p:P_IN-XMLTYPE-IN>
</p:P_TABLEASWS_XMLIN_XMLOUTInput>
</soapenv:Body>
</soapenv:Envelope>
Getting Output -:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<P_TABLEASWS_XMLIN_XMLOUTOutput xmlns="http://xmlns.oracle.com/orawsv/TEST/P_TABLEASWS_XMLIN_XMLOUT">
<P_OUT>
<employees>
<employee>
<empno>1</empno>
<ename>ONE</ename>
</employee>
<employee>
<empno>2</empno>
<ename>TWO</ename>
</employee>
</employees>
</P_OUT>
</P_TABLEASWS_XMLIN_XMLOUTOutput>
</soap:Body>
</soap:Envelope>
Problem is -:
a) I have manually added each column in the procedure.
If any new column is added, procedure needs to be modified
b) XMLTABLE output column type has to be hard coded.
Unable to define column as TABLE_NAME.COLUM_NAME%TYPE

Could Not Get Columns with XMLTABLE in Oracle PL/SQL

I try to get values from columns of a XML file.
I receive XML file which in my function is assigned to c_xml but for the purposes of this question is represented in the variable c_xml in the code below.
The problem is that I have not anything printed in DBMS_OUTPUT. PUT_LINE, so I could not get any values from XML file and I could not go further with my developing.
It would be great if somebody could help to understand where is the problem with extracting values from this XML. Thanks for your time :)
The code is written on Oracle PL/SQL and follows:
DECLARE
c_xml xmltype;
BEGIN
c_xml :=
xmltype
('<?xml version=''1.0'' encoding=''utf-8''?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header/>
<env:Body>
<srvc:returnActStateByEgnResponse xmlns="http://curr_state_egn/CURR_STATE_EGNService" xmlns:srvc="http://curr_state_egn/CURR_STATE_EGNServiceService">
<srvc:result>
<consents_tblType>
<item>
<req_id>112</req_id>
<purpose_code>CC0100</purpose_code>
<consent_state>0</consent_state>
</item>
<item>
<req_id>112</req_id>
<purpose_code>CC0200</purpose_code>
<consent_state>1</consent_state>
</item>
<item>
<req_id>112</req_id>
<purpose_code>CC0300</purpose_code>
<consent_state>0</consent_state>
</item>
</consents_tblType>
</srvc:result>
</srvc:returnActStateByEgnResponse>
</env:Body>
</env:Envelope>');
FOR consents_tblTypes IN
( SELECT
p_req_id
, p_purpose_code
, p_consent_state
FROM xmltable(
XMLNamespaces(
'http://schemas.xmlsoap.org/soap/envelope/' AS "env"
--, 'http://www.w3.org/2001/XMLSchema-instance' AS "xsi"
, 'http://curr_state_egn/CURR_STATE_EGNServiceService' AS "srvc"
),
'/env:Envelope/env:Body/srvc:returnActStateByEgnResponse/srvc:result/consents_tblType/item'
PASSING c_xml
COLUMNS
p_req_id NUMBER PATH 'req_id' --/text()
, p_purpose_code VARCHAR2(20) PATH 'purpose_code' --/text()
, p_consent_state NUMBER PATH 'consent_state' --/text()
)
)
LOOP
DBMS_OUTPUT.put_line('p_req_id = ' || to_char(consents_tblTypes.p_req_id)) ;
DBMS_OUTPUT.put_line('p_purpose_code = ' || consents_tblTypes.p_purpose_code) ;
DBMS_OUTPUT.put_line('p_consent_state = ' || to_char(consents_tblTypes.p_consent_state)) ;
END LOOP;
end;
Default namespace has to be included in the declaration.
XMLNamespaces('http://schemas.xmlsoap.org/soap/envelope/' AS "env"
, 'http://curr_state_egn/CURR_STATE_EGNServiceService' AS "srvc"
, default 'http://curr_state_egn/CURR_STATE_EGNService')
This statment xmlns="http://curr_state_egn/CURR_STATE_EGNService" changes defult namespaces.

How to convert XMLTYPE in VARCHAR in ORACLE?

I have two columns in my table(TRANSACTION) in ORACLE which are XMLTYPE(XML_IN and XML_OUT). My procedure is not working because I don't know how to convert them to VARCHAR or something(I just think that this is the error). My procedure is:
PROCEDURE SEARCH_XML
(
P_ID_TRANSACTION IN TRANSACTION.ID_TRANSACTION%TYPE,
P_CURSOR OUT T_CURSOR
)
IS
BEGIN
OPEN P_CURSOR FOR
SELECT T.XML_IN, T.XML_OUT
FROM TRANSACTION T
WHERE T.ID_TRANSACTION = P_ID_TRANSACTION;
END SEARCH_XML;
When I call this procedure error message in VisualStudio2008 is: "Unsupported oracle data type USERDEFINED encountered." Any idea how is this working?
XMLType has two methods: getStringVal() and getClobVal() which will convert the XML structure to their string representations (as a VARCHAR2 and CLOB respectively). Unless you know that your XML output is going to always be less than 4000 characters (bytes) then you will probably want to use getClobVal() like this:
PROCEDURE SEARCH_XML
(
P_ID_TRANSACTION IN TRANSACTION.ID_TRANSACTION%TYPE,
P_CURSOR OUT T_CURSOR
)
IS
BEGIN
OPEN P_CURSOR FOR
SELECT T.XML_IN.getClobVal() AS XML_IN,
T.XML_OUT.getClobVal() AS XML_OUT
FROM TRANSACTION T
WHERE T.ID_TRANSACTION = P_ID_TRANSACTION;
END SEARCH_XML;

To change column datatype from clob to xmltype

I have a table which has around one thousand records in it and one of the column is of data type CLOB which now I has to convert to XMLType due to some other reasons.
How do i convert the column from CLOB to XMLType?
Thanks
You can try to do it like this:
Add a column having data type as XML Type in your table.
Copy the data of clob column to the newly added xmltype column.
Drop the clob column.
Rename the xmltype column to the name of your original column.
Something like this:
alter table yourtable
add (temp_col xmltype);
update yourtable
set temp_col = xmltype.createxml(clobCol);
alter table yourtable
drop column clobCol;
alter table yourtable
rename column temp_col to clobCol;
You can do something like this using DBMS_XMLPARSER package:
-- Variables used for parsing the XML document
xml_ CLOB := 'X';
p DBMS_XMLPARSER.parser;
doc_ DBMS_XMLDOM.DOMDocument;
node_list_ DBMS_XMLDOM.DOMNodeList;
node_len_ NUMBER;
-- Convert the CLOB into a XML-document enter code here
P := DBMS_XMLPARSER.newparser();
-- Parse the clob and get the XML-document
DBMS_XMLPARSER.parseclob(p, xml_);
-- Note that the document is parsed in local CSID even thought the xml contains UTF8, strange but it seems to work
doc_ := DBMS_XMLPARSER.getDocument(p);
--- Bug 114812 SPM Start
node_list_ := DBMS_XMLDOM.getElementsByTagName(doc_, 'NODETOEXTRACT');
node_len_ := DBMS_XMLDOM.getLength(node_list_);
NOTE :- xml_ variable should contain the message in CLOB format to parse it. If the XML is in BLOB you could use this method to convert to CLOB
-- Convert the BLOB-message into a CLOB
DBMS_LOB.converttoclob(dest_lob => xml_,
src_blob => message_value_,
amount => dbms_lob.lobmaxsize,
dest_offset => l_dest_offsset_,
src_offset => l_src_offsset_,
blob_csid => 871, -- 871 is UTF8
lang_context => l_lang_context_,
warning => l_warning_);

Oracle: How do I display DBMS_XMLDOM.DOMDocument for debugging?

Running Oracle 10g, Sqldeveloper 1.5.5
I want to view the contents of an DBMS_XMLDOM.DOMDocument as a string in the output or results window in sqldeveloper. or some other simple way to debug this thing...
Thanks,P
DBMS_XMLDOM.WRITETOBUFFER Writes the contents of the node to a buffer.
DBMS_XMLDOM.WRITETOCLOB Writes the contents of the node to a CLOB.
DBMS_XMLDOM.WRITETOFILE Writes the contents of the node to a file.
I have PL/SQL code that wites it to the file system using a DIRECTORY:
dbms_xmldom.writeToFile(dbms_xmldom.newDOMDocument( xmldoc)
,'DATAPUMPDIR/myfile.xml') ;
I have created a function using dbms_xmldom.writetoclob
create or replace function xml2clob (xmldoc XMLType) return CLOB is
clobdoc CLOB := ' ';
begin
dbms_xmldom.writeToClob(dbms_xmldom.newDOMDocument( xmldoc)
,clobdoc) ;
return clobdoc;
end;
/
Query:
SELECT xml2clob(Sys_Xmlagg(
Xmlelement(Name "dummy"
,dummy
),Xmlformat('dual')))
FROM dual;
Output:
<?xml version="1.0"?>
<dual>
<dummy>X</dummy>
</dual>
You could try using a function like this:
create or replace function dom2clob (domdoc DBMS_XMLDOM.DOMDocument) return CLOB is
clobdoc CLOB := ' ';
begin
dbms_xmldom.writeToClob(domdoc,clobdoc) ;
return clobdoc;
end;
/
You can accomplish the same as in:
"SELECT xml2clob(Sys_Xmlagg(Xmlelement(Name "dummy",dummy),Xmlformat('dual'))) FROM dual;"
with:
SELECT
Sys_Xmlagg(Xmlelement(Name "dummy",dummy)
,Xmlformat('dual')).Extract('/*').getClobVal() as "test"
FROM dual;
and you do not have to create the function "xml2clob"
.Extract('/*') is for "pretty printing"
output:
<dual>
<dummy>X</dummy>
</dual>
If you already have an xmltype simply use the function getClobVal()
xmldoc.getClobVal()
This returns your XMLType as a clob without the additional function overhead.

Resources