Insert xml Node into a CLOB column with namespace in Oracle - oracle

I have next below xml value in CLOB column in Oracle 11g.
<Energy xmlns="http://euroconsumers.org/notifications/2009/01/notification">
<WEBSITE>WWW.VERLAAG.BE</WEBSITE>
<CUSTOMERID>xxxxxx</CUSTOMERID>
<Gender>M</Gender>
<Telephone>0000000000</Telephone>
</Energy>
I want to add a new node called: Language
to look like this:
<Energy xmlns="http://euroconsumers.org/notifications/2009/01/notification">
<WEBSITE>WWW.VERLAAG.BE</WEBSITE>
<CUSTOMERID>xxxxxx</CUSTOMERID>
<Gender>M</Gender>
<Telephone>0000000000</Telephone>
<Language></Language>
</Energy>
I've used next below sentence:
update tmp_tab_noemail_test_aankoop p1
set p1.sce_msg = insertchildxml(p1.sce_msg, '/Energy', 'Language',
xmltype('<Language><Language/>'),
'xmlns="http://euroconsumers.org/notifications/2009/01/notification')
.getclobval();
And also this one:
update tmp_tab_noemail_test_aankoop p1
set p1.sce_msg = APPENDCHILDXML(p1.sce_msg,
'/Energy',
XMLType('<Language><Language/>'),
'xmlns="http://euroconsumers.org/notifications/2009/01/notification')
.getclobval()
But any of these functions are working.
Any idea?

In both of your statements you are not converting your initial CLOB to XMLType, and your closing tag for the new node is malformed - you have <Language/> instead of </Language>. Either provide opening and closing tags, or a single self-closing one, not a mix of both. You're also missing the closing double-quote in your namespace.
These both work:
update tmp_tab_noemail_test_aankoop p1
set p1.sce_msg = insertchildxml(XMLType(p1.sce_msg), '/Energy', 'Language',
XMLType('<Language></Language>'),
'xmlns="http://euroconsumers.org/notifications/2009/01/notification"').getclobval();
Or:
update tmp_tab_noemail_test_aankoop p1
set p1.sce_msg = APPENDCHILDXML(XMLType(p1.sce_msg), '/Energy',
XMLType('<Language></Language>'),
'xmlns="http://euroconsumers.org/notifications/2009/01/notification"').getclobval();
The latter looks a little better as the new tag appears as
<Language/>
rather than
<Language xmlns=""/>
You can preserve the namespace with insertchild but then it appears explicitly in the new node even though it matches the top-level Energy namespace; which doesn't matter functionally but looks a bit odd.

Related

Fetch value from XML using dynamic tag in ESQL

I have an xml
<family>
<child_one>ROY</child_one>
<child_two>VIC</child_two>
</family>
I want to fetch the value from the XML based on the dynamic tag in ESQL. I have tried like this
SET dynamicTag = 'child_'||num;
SET value = InputRoot.XMLNSC.parent.(XML.Element)dynamicTag;
Here num is the value received from the input it can be one or two. The result should be value = ROY if num is one and value is VIC if num is two.
The chapter ESQL field reference overview describes this use case:
Because the names of the fields appear in the ESQL program, they must be known when the program is written. This limitation can be avoided by using the alternative syntax that uses braces ( { ... } ).
So can change your code like this:
SET value = InputRoot.XMLNSC.parent.(XMLNSC.Element){dynamicTag};
Notice the change of the element type as well, see comment of #kimbert.

How to get value from a column referenced by a number, from JDBC Response object of Jmeter?

I know they advice to get a cell value this way:
columnValue = vars.getObject("resultObject").get(0).get("Column Name");
as stated on jMeter doc : component reference : JDBC_Request.
But: How to access the same RS cell value by just a number of the column?
RS.get(0).get(4);
...instead of giving it a String of column Name/Label.
edit 1: Lets use Groovy/Java, instead of BeanShell. Thanks.
edit 2: The original motivation was the difference between column Name / Label, as these seem to be not fully guaranteed (? seems to be not clear here, not to me), especially due case-sensitivity ("id"/"ID", "name"/"Name"/"NAME" ..)
It should be something like:
String value = (new ArrayList<String>(vars.getObject("resultObject").get(0).values())).get(4)
More information: Debugging JDBC Sampler Results in JMeter
Be aware that according to HashMap documentation:
This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
So the order of columns might be a big question mark.
The row itself is a HashMap, defined in source code as:
HashMap<String, Object> row
So using BeanShell syntax, you could get it as
row = vars.getObject("resultObject").get(0); // returns HashMap
In HashMap, you cannot access item (column) by ID. You could, however, apply one of the methods described here, but HashMap doesn't guarantee order, so you cannot be sure what "column 4" will contain.
If you want to be able to loop through all columns, it's better to do it in a Map style, not by index. For example using entrySet() with BeanShell:
for(Map.Entry entry : row.entrySet())
{
log.info(entry.getKey() + "=" + entry.getValue());
}
See various ways to iterate through Map here.

How to WRITE a structure?

How can I do the following:
data: ls_header type BAPIMEPOHEADER.
" fill it
write ls_header.
currently I'm getting an error because write can not parse the complex type to a string. Is there a simple way to get this code running in abap?
You could use something like:
DATA: g_struct TYPE bapimepoheader.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE g_struct TO FIELD-SYMBOL(<f>).
IF sy-subrc NE 0.
EXIT.
ENDIF.
WRITE: / <f>.
ENDDO.
Perhaps not exactly the answer you expect: If you list each field.
This can be done quite easy via the Pattern-mask in SE38:
Select the Write-pattern:
Enter the structure you want:
Select the fields
Confirm with "Copy"
Confirm and you get
WRITE: bapimepoheader-po_number,
bapimepoheader-comp_code,
bapimepoheader-doc_type,
bapimepoheader-delete_ind,
bapimepoheader-status,
bapimepoheader-creat_date,
bapimepoheader-created_by,
bapimepoheader-item_intvl,
bapimepoheader-vendor,
bapimepoheader-langu,
bapimepoheader-langu_iso,
bapimepoheader-pmnttrms,
bapimepoheader-dscnt1_to,
bapimepoheader-dscnt2_to,
bapimepoheader-dscnt3_to,
bapimepoheader-dsct_pct1,
bapimepoheader-dsct_pct2,
bapimepoheader-purch_org,
bapimepoheader-pur_group,
bapimepoheader-currency,
bapimepoheader-currency_iso,
bapimepoheader-exch_rate,
bapimepoheader-ex_rate_fx,
bapimepoheader-doc_date,
bapimepoheader-vper_start,
bapimepoheader-vper_end,
bapimepoheader-warranty,
bapimepoheader-quotation,
bapimepoheader-quot_date,
bapimepoheader-ref_1,
bapimepoheader-sales_pers,
bapimepoheader-telephone,
bapimepoheader-suppl_vend,
bapimepoheader-customer,
bapimepoheader-agreement,
bapimepoheader-gr_message,
bapimepoheader-suppl_plnt,
bapimepoheader-incoterms1,
bapimepoheader-incoterms2,
bapimepoheader-collect_no,
bapimepoheader-diff_inv,
bapimepoheader-our_ref,
bapimepoheader-logsystem,
bapimepoheader-subitemint,
bapimepoheader-po_rel_ind,
bapimepoheader-rel_status,
bapimepoheader-vat_cntry,
bapimepoheader-vat_cntry_iso,
bapimepoheader-reason_cancel,
bapimepoheader-reason_code,
bapimepoheader-retention_type,
bapimepoheader-retention_percentage,
bapimepoheader-downpay_type,
bapimepoheader-downpay_amount,
bapimepoheader-downpay_percent,
bapimepoheader-downpay_duedate,
bapimepoheader-memory,
bapimepoheader-memorytype,
bapimepoheader-shiptype,
bapimepoheader-handoverloc,
bapimepoheader-shipcond,
bapimepoheader-incotermsv,
bapimepoheader-incoterms2l,
bapimepoheader-incoterms3l.
Now you can make a simple replacement of bapimepoheader with ls_header and you have an output of all fields of the structure.
Maybe this is not elegant and you must adapt your report, if the structure changes. But I like this way, because often I don't need all fields and I can select the fields in an easy way.
I know two ways, one is procedural, the other is oop.
Here is the procedural approach.
Select the structure's fields (or whatever else You might need ) from the data-dictionary table DD03L into a local internal table.
Loop over the table into a work-area
Check, whether current field is a flat single datatype, and if so,
Assign component workarea-fieldname of structure ls_header into anyfieldsymbol
Write anyfieldsymbol
Do You need the code ?
Class CL_ABAP_CONTAINER_UTILITIES was specially introduced for that by SAP.
Use FILL_CONTAINER_C method for output the structure in a WRITE manner:
DATA: ls_header type BAPIMEPOHEADER.
CALL METHOD CL_ABAP_CONTAINER_UTILITIES=>FILL_CONTAINER_C
EXPORTING
IM_VALUE = ls_header
IMPORTING
EX_CONTAINER = DATA(container)
EXCEPTIONS
ILLEGAL_PARAMETER_TYPE = 1
others = 2.
WRITE container.
You can write your structure to a string and then output the string. Same method idoc segments are created.

Inserting a child node when list is empty (XForms)

My problem is the following :
I usually have those data:
<structures>
<structure id="10">
<code>XXX</code>
</structure>
</structures>
so the table I display (single columns : code) is ok.
But in some cases, the data is the result a a query with no content, so the data is:
<structures/>
resulting in my table not displaying + error.
I am trying to insert, in the case of an empty instance, a single node so that the data would look like:
<structures>
<structure id="0"/>
</structures>
I am trying something like that :
<xforms:action ev:event="xforms-submit-done">
<xforms:insert if="0 = count(instance('{./instance-name}')/root/node())" context="instance('{./instance-name}')/root/node()" origin="xforms:element('structure', '')" />
</xforms:action>
but no node inserted when I look at the data in the inspector in the page.
Any obvious thing I am doing wrong?
There seems to be erros in your XPath if and context expressions:
if="0 = count(instance('{./instance-name}')/root/node())"
context="instance('{./instance-name}')/root/node()"
You are a using curly brackets { and }, I assume to have the behavior of attribute value templates (AVTs). But the if and context expressions are already XPath expressions, so you cannot use AVTs in them. Try instead:
if="0 = count(instance(instance-name)/root/node())"
context="instance(instance-name)/root/node()"
Also, the instance-name path is relative to something which might not be clear when reading or writing the expression. I would suggest using an absolute path for example instance('foo')/instance-name to make things clearer.
You don't provide the structure of the other instances, so I can tell for sure, but you'll expression above suppose that they have the form:
<xf:instance id="foo">
<some-root-element>
<root>
<structure/>
</root>
<some-root-element>
</xf:instance>
I don't know if that's what you intend.
Finally, you could replace count(something) = 0, with empty(something).

Dynamic XPath Creation in SQL Server

I have an XML and I want to get the Xml Node values dynamically. I want to Pass the Node Name and the in return the function or SP should return me the value of that Node.
<ClassificationTypeEntity>
<LTABLE_ID>3170</LTABLE_ID>
<LTABLE_CODE>script Code</LTABLE_CODE>
<LTABLE_DESC>alert(''hello'')</LTABLE_DESC>
<ACTIVE_YES_NO>1</ACTIVE_YES_NO>enter code here
<PRIVATE_FILING>0</PRIVATE_FILING>
<RETENTION_CODE /><RETENTION_TITLE />
<LTABLE_ID_P>0</LTABLE_ID_P>
</ClassificationTypeEntity>;
For Example, In the above xml, when I want the value of LTABLE_CODE Node, I will pass the same and the result should I get is
script code
Same for LTABLE_DESC the result should be alert(''hello'')
However I can write the 2 Xpath query for both but in case my schema gets changed (more properties added or removed) then I will have to change my SP also.
Thanks,
Mohit Jain
Thanks for your replies.
I have found the solution:
declare #xmlData xml, #NodeName VarChar(500), #nodeValue VarChar(500)
Set #NodeName = 'LTABLE_CODE';
--Set #NodeName = 'LTABLE_DESC';
set #xmlData =
'<ClassificationTypeEntity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LTABLE_ID>3170</LTABLE_ID>
<LTABLE_CODE><script>al</LTABLE_CODE>
<LTABLE_DESC><script>alert(''hello'')</script></LTABLE_DESC>
<ACTIVE_YES_NO>1</ACTIVE_YES_NO>
<PRIVATE_FILING>0</PRIVATE_FILING>
<RETENTION_CODE /><RETENTION_TITLE />
<LTABLE_ID_P>0</LTABLE_ID_P>
</ClassificationTypeEntity>'
SET #nodeValue = #xmlData.value('(/ClassificationTypeEntity/*[local-name()=sql:variable("#NodeName")])[1]','nvarchar(max)')
SELECT #nodeValue

Resources