Author |
Message
|
catshout |
Posted: Sat Aug 10, 2013 12:08 am Post subject: Cast a HTTP XML output as BLOB into a Collection |
|
|
Acolyte
Joined: 15 May 2012 Posts: 57
|
Dear all,
after some hours of testing and researching (even here) I'm gonna to post my issue within this forum.
The requirement I'm trying to solve is following:
1. Capture some data as XML from another flow that publishes the data via HTTP. I've saved the data with SoapUI DataSink and stored here
http://catshout.de/resource.xml
2. Select a subtree with a given name and cast it to XMLNSC domain
3. Cast the result from XMLNSC finally to a Collection element als BLOB (the following node requires a Collection with childs casted as BLOBs)
I've checked these post within the forum
http://www.mqseries.net/phpBB/viewtopic.php?p=269723&sid=cd2d59d0ebec9e45da6d8cc13571b467
http://www.mqseries.net/phpBB/viewtopic.php?t=54164&sid=2f4326d4005dd3c934d431cbfed82b16
http://www.mqseries.net/phpBB2/viewtopic.php?t=57024&sid=81c4ed3d1cd3e9cdfe8cecb347c399eb
Finally I was coming to this code (snippets)
Code: |
...
CREATE LASTCHILD OF Environment.ResourceRequest;
CREATE LASTCHILD OF Environment DOMAIN 'XMLNSC';
...
(HTTPRequest Node here with XMLNSC Parser option and Environment.ResourceRequest as target)
...
SET Environment.XMLNSC.rows[] =
(SELECT * FROM Environment.ResourceRequest.resources.resource.rows[] WHERE Environment.ResourceRequest.resources.resource.name = 'TVPP_ID');
-- Declare a couple variables...
DECLARE msgBody BLOB;
DECLARE msgBodyChar CHAR;
-- Set the BLOB to be the whole XML tree, the defaults (OPTIONS RootBitStream & ValidateNone, CCSID and ENCODING 0 and set, type and format '') are fine:
SET msgBody = ASBITSTREAM(Environment.XMLNSC);
-- Convert the BLOB to a character string, handy for adding into other non-xml messages with embedded messages (and for tracing)...
SET msgBodyChar = CAST(msgBody AS CHAR CCSID 1208 ENCODING InputProperties.Encoding);
-- Use the above string as a subtree of an existing XMLNSC tree
CREATE LASTCHILD OF Environment.XMLNSC.TVPP_ID PARSE(msgBodyChar,InputProperties.Encoding);
SET OutputRoot.Collection.TVPP_ID.BLOB.BLOB =
ASBITSTREAM(Environment.XMLNSC.TVPP_ID, InputRoot.Properties.Encoding, InputRoot.Properties.CodedCharSetId);
...
|
The code runs (I'm debugging all the time), the subtree is being created under Environment.XMLNSC.TVPP_ID, but finally the OutputRoot.Collection.TVPP_ID.BLOB.BLOB is an empty one. No errors at all while debugging.
I've reduced the subtree to a smaller amount of elements (e.g. 10) and stepwise upwards. With ROWNUM <= 81 the whole thing works as expected. More than 81 rows are failing.
So far my questions are ..
1. Is there a size limitation for such cast use cases?
2. Could it be a cast option issue (e.g. charset, encoding, validating one)?
3. Could it be done in a simpler way?
I quite new to ESQL coding, so far I apologize for some things that might be obviously in your opinion. Anyway, I'd more than happy about any responses and hints to solve my requirement.
Best regards
- Gerald |
|
Back to top |
|
 |
dogorsy |
Posted: Sat Aug 10, 2013 2:33 am Post subject: |
|
|
Knight
Joined: 13 Mar 2013 Posts: 553 Location: Home Office
|
I can see what you are doing, and I can see a few things that can be wrong, but rather than fixing your code, why don't you explain exactly WHAT you want to do ? probably there is a better way of doing it.
For example: This is my input XML message ( attach message )(whether it comes from HTTP, SOAP or MQ is irrelevant, so no need to mention that ),
and I want this to be my output ( the subtree ? , again, whether it goes to collection or queue is irrelevant.., what you want is to get the transformation right )...
then you can code that, output as xml to start with, once you are happy that you are getting the right output, convert to BLOB...
If, as you say, you are new to ESQL, then it is better to do small steps, and move on once you are happy and confident with whatever you have achieved. |
|
Back to top |
|
 |
catshout |
Posted: Sat Aug 10, 2013 5:51 am Post subject: |
|
|
Acolyte
Joined: 15 May 2012 Posts: 57
|
Many thanks for the reply. Ok, so let's start to explain the use case more in detail ..
1. That's the input XML I'm going to start with (in my case I'm capturing it with a HTTPRequest node)
http://catshout.de/resource.xml
It follows this structure ..
Code: |
<resources>
<resource name="TVPP_ID">
<rows>
<row>
<OASE_ID>...</OASE_ID>
<MESSAGE_ID>...</MESSAGE_ID>
<TRANSACTION_ID>...</TRANSACTION_ID>
<LAST_UPDATED/>
</row>
... some more rows
</rows>
</resource>
<resource name="TVPP_Keys">
<rows>
... similar to above
</rows>
</resource>
</resources> |
2. Select one subtree matching a given name attribute
3. Cast the whole subtree into a BLOB and put in anywhere in a message tree (in my case as Collection child element value)
Seems to be simple but there might be some pitfalls (for me).
Again, many thanks in advance for any hints.
Best
- Gerald |
|
Back to top |
|
 |
dogorsy |
Posted: Sat Aug 10, 2013 6:04 am Post subject: |
|
|
Knight
Joined: 13 Mar 2013 Posts: 553 Location: Home Office
|
ok, so your subtree would be one of
Code: |
<resource name="TVPP_ID">
<rows>
<row>
<OASE_ID>...</OASE_ID>
<MESSAGE_ID>...</MESSAGE_ID>
<TRANSACTION_ID>...</TRANSACTION_ID>
<LAST_UPDATED/>
</row>
... some more rows
</rows>
</resource>
|
and you select it depending on the name ?, in this case "TVPP_ID"
is that correct ?
Code: |
-- create a temporary folder named xmlnsc and associate it with the xmlnsc parser
CREATE LASTCHILD OF Environment DOMAIN 'XMLNSC' NAME 'XMLNSC';
SET Environment.XMLNSC.rows[] =
(SELECT * FROM InputRoot.XMLNSC.resources.resource[] AS I WHERE I.(XMLNSC.Attribute)name = 'TVPP_ID');
|
start with that, that should move the subtree you want to the environment, to verify it is what you want, copy to OutputRoot and look at the message. post the output here.
Once you are happy, we can cast to blob
and you may need to name the element in the env tree resource rather thatn rows:
Code: |
SET Environment.XMLNSC.resource[] = |
but not sure. Just try it. |
|
Back to top |
|
 |
catshout |
Posted: Sat Aug 10, 2013 8:54 am Post subject: |
|
|
Acolyte
Joined: 15 May 2012 Posts: 57
|
Many thanks for the reply. That's the 1st part of my code right now I've already posted that is doing the subtree selection as I want
Code: |
CREATE LASTCHILD OF Environment.ResourceRequest;
CREATE LASTCHILD OF Environment DOMAIN 'XMLNSC';
...
(HTTPRequest Node here with XMLNSC Parser option and Environment.ResourceRequest as target)
...
SET Environment.XMLNSC.rows[] =
(SELECT * FROM Environment.ResourceRequest.resources.resource.rows[] WHERE Environment.ResourceRequest.resources.resource.name = 'TVPP_ID'); |
The output does have the following structure
Code: |
<rows>
<row>
<OASE_ID>...</OASE_ID>
<MESSAGE_ID>...</MESSAGE_ID>
<TRANSACTION_ID>...</TRANSACTION_ID>
<LAST_UPDATED/>
</row>
... some more rows
</rows>
|
and contains the subtree matching the attribute name 'TVPP_ID'.
The part I'm really struggling with ist the CAST into a BLOB.
Best
- Gerald |
|
Back to top |
|
 |
dogorsy |
Posted: Sat Aug 10, 2013 9:08 am Post subject: |
|
|
Knight
Joined: 13 Mar 2013 Posts: 553 Location: Home Office
|
yes, I have seen that, but as I said, I don't understand why you copy the input to the environment and then do a select when you can do the select directly.
and then you have the following
Code: |
...
(HTTPRequest Node here with XMLNSC Parser option and Environment.ResourceRequest as target)
...
|
which does not make sense. you cannot have an httprequest node with xmlnsc parser option ?!!! in the middle of your esql.
and is the msg below what is being produced or what you want to produce ?
Quote: |
The output does have the following structure
Code:
<rows>
<row>
<OASE_ID>...</OASE_ID>
<MESSAGE_ID>...</MESSAGE_ID>
<TRANSACTION_ID>...</TRANSACTION_ID>
<LAST_UPDATED/>
</row>
... some more rows
</rows>
and contains the subtree matching the attribute name 'TVPP_ID'.
|
The reason I am asking is because I have doubts your select is doing what you think it is doing, and then blaming the CAST. That is why I asked you to do one step at a time and prove it is correct.
So, I would like you to put a trace node and output your Environment.XMLNSC tree |
|
Back to top |
|
 |
catshout |
Posted: Sat Aug 10, 2013 9:17 am Post subject: |
|
|
Acolyte
Joined: 15 May 2012 Posts: 57
|
Many thanks for the reply.
Quote: |
yes, I have seen that, but as I said, I don't understand why you copy the input to the environment and then do a select when you can do the select directly.
and then you have the following
Code:
Code: |
...
(HTTPRequest Node here with XMLNSC Parser option and Environment.ResourceRequest as target)
... |
which does not make sense. you cannot have an httprequest node with xmlnsc parser option ?!!! in the middle of your esql. |
The current HTTPRequest Node in 8.0.0.2 gives me the XMLNSC Parser option and so far I'm copying the output directly under an XMLNSC domain. Would you suggest an other way?
Of course, the SELECT can be done directly, at the moment I'm getting the subtree as I want. This I'll check.
Quote: |
and is the msg below what is being produced or what you want to produce ? |
Yes, it is. The subtree is already what I want. I'm already interested getting the CAST into a BLOB solved as this still fails.
Best
- Gerald |
|
Back to top |
|
 |
Simbu |
Posted: Sat Aug 10, 2013 9:21 am Post subject: |
|
|
 Master
Joined: 17 Jun 2011 Posts: 289 Location: Tamil Nadu, India
|
catshout wrote: |
Code: |
SET Environment.XMLNSC.rows[] =
(SELECT * FROM Environment.ResourceRequest.resources.resource.rows[] WHERE Environment.ResourceRequest.resources.resource.name = 'TVPP_ID'); |
|
Hi catshout, I don't think your select query works for resources.resource.name = 'TVPP_Keys'
Code: |
SET Environment.XMLNSC.rows[] =
(SELECT * FROM Environment.ResourceRequest.resources.resource.rows[] WHERE Environment.ResourceRequest.resources.resource.name = 'TVPP_Keys'); |
Instead you can use the query that dogorsy posted
Code: |
-- create a temporary folder named xmlnsc and associate it with the xmlnsc parser
CREATE LASTCHILD OF Environment DOMAIN 'XMLNSC' NAME 'XMLNSC';
SET Environment.XMLNSC.rows[] =
(SELECT * FROM InputRoot.XMLNSC.resources.resource[] AS I WHERE I.(XMLNSC.Attribute)name = 'TVPP_ID'); |
also please post the full exception list that you are getting. |
|
Back to top |
|
 |
dogorsy |
Posted: Sat Aug 10, 2013 9:35 am Post subject: |
|
|
Knight
Joined: 13 Mar 2013 Posts: 553 Location: Home Office
|
The best thing you can do is to get a user trace, then you can see where the code is failing, and use a trace node to show us the environment tree.
Quote: |
The current HTTPRequest Node in 8.0.0.2 gives me the XMLNSC Parser option and so far I'm copying the output directly under an XMLNSC domain. Would you suggest an other way?
|
As I said before, where the message comes from is irrelevant. What is important is that you get an xml message, use the xmlnsc parser and do not need to copy it to the environment. That is why I gave you the code, just two lines, first to create a folder in the environment and then the select to get the subtree you want. ( so that answer your question, I was suggesting another way, a far easier one )
Of course you can do anything you want, but then people will have problems understanding the code when they need to update it. |
|
Back to top |
|
 |
catshout |
Posted: Sat Aug 10, 2013 1:53 pm Post subject: |
|
|
Acolyte
Joined: 15 May 2012 Posts: 57
|
Thanks for the replies.
As I mentioned, the issue is NOT selecting the right subtree. This already works.
The main issue how is to CAST the subtree into a BLOB. Please focus on that.
Many thanks
- Gerald |
|
Back to top |
|
 |
dogorsy |
Posted: Sat Aug 10, 2013 10:00 pm Post subject: |
|
|
Knight
Joined: 13 Mar 2013 Posts: 553 Location: Home Office
|
catshout wrote: |
Thanks for the replies.
As I mentioned, the issue is NOT selecting the right subtree. This already works.
The main issue how is to CAST the subtree into a BLOB. Please focus on that.
Many thanks
- Gerald |
Two people trying to help and you are not cooperating. CAST is well documented so work it out yourself if you are so clever. |
|
Back to top |
|
 |
fjb_saper |
Posted: Sat Aug 10, 2013 10:03 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
catshout wrote: |
Thanks for the replies.
As I mentioned, the issue is NOT selecting the right subtree. This already works.
The main issue how is to CAST the subtree into a BLOB. Please focus on that.
Many thanks
- Gerald |
I believe the reason nobody is focusing on this, is because it is irrelevant. You don't need to transform the XMLNSC into a BLOB to send it over the HTTPRequest node...  _________________ MQ & Broker admin |
|
Back to top |
|
 |
catshout |
Posted: Sat Aug 10, 2013 10:31 pm Post subject: |
|
|
Acolyte
Joined: 15 May 2012 Posts: 57
|
Quote: |
I believe the reason nobody is focusing on this, is because it is irrelevant. You don't need to transform the XMLNSC into a BLOB to send it over the HTTPRequest node... |
Ok, it might be stated not clear enough from mine.
I'm getting some XML from anywhere (yes it's from HTTP Request, but this is irrelevant).
I want to hand over the XML as BLOB to the next Node. (This next one is a WTX Node that is expecting a Collection with childs as BLOBs, but this is irrelavant too.)
So far I need to CAST the XML into a BLOB. That's the case. |
|
Back to top |
|
 |
dogorsy |
Posted: Sat Aug 10, 2013 11:11 pm Post subject: |
|
|
Knight
Joined: 13 Mar 2013 Posts: 553 Location: Home Office
|
catshout wrote: |
Quote: |
I believe the reason nobody is focusing on this, is because it is irrelevant. You don't need to transform the XMLNSC into a BLOB to send it over the HTTPRequest node... |
Ok, it might be stated not clear enough from mine.
I'm getting some XML from anywhere (yes it's from HTTP Request, but this is irrelevant).
I want to hand over the XML as BLOB to the next Node. (This next one is a WTX Node that is expecting a Collection with childs as BLOBs, but this is irrelavant too.)
So far I need to CAST the XML into a BLOB. That's the case. |
The problem here is not CAST. The problem is that you are not listening to what people are trying to say and keep muddling the water by mentioning http, collection, etc. and insisting in CAST.
Run a user trace and see where your code is wrong, and probably you will find that your code is not doing what you think it is doing.
OR, output your message as XML to start with, as I suggested earlier in this thread. So you can demonstrate to us that you are getting the right subtree. |
|
Back to top |
|
 |
catshout |
Posted: Sun Aug 11, 2013 3:51 am Post subject: |
|
|
Acolyte
Joined: 15 May 2012 Posts: 57
|
Ok, I did follow your suggestion. One step only.
I created a simple flow with an incoming message and one EQSL node with a SELECT statement. The message was written afterwards to a file.
The input XML was this one
Code: |
<resources>
<resource name="TVPP_ID">
<rows>
<row>
<OASE_ID>0331703945813728346402916</OASE_ID>
<MESSAGE_ID>ID:9eed21fb-f57c-4690-b673-d0f1f08b41dd@JSESSIONID=T1XKS0WDVHQYY7T5WADW6XURQX0Q3LYB.mo11261_b2b1</MESSAGE_ID>
<TRANSACTION_ID>c022c241-96cf-4f70-b5ac-62cf4477136c</TRANSACTION_ID>
<LAST_UPDATED>2013-07-03T11:42:30.420</LAST_UPDATED>
</row>
<row>
<OASE_ID>8888913032100002</OASE_ID>
<MESSAGE_ID>ID:d9b8fde1-7d75-4f6e-acf7-86a0bae56415@JSESSIONID=8QK3X7NOWF0P8EBIOGLSFHBLZL5U3BBX.mo11261_b2b1</MESSAGE_ID>
<TRANSACTION_ID>a3b71450-9f0f-4408-9bac-a5a8963c5e28</TRANSACTION_ID>
<LAST_UPDATED>2013-07-04T09:18:15</LAST_UPDATED>
</row>
</rows>
</resource>
<resource name="TVPP_Keys">
<rows>
<row>
<CGROUP>TVPP</CGROUP>
<SUB_GROUP>IDENTIFICATIONFORM</SUB_GROUP>
<KEY>AG i. G.</KEY>
<VALUE>NO_REGISTER</VALUE>
</row>
<row>
<CGROUP>TVPP</CGROUP>
<SUB_GROUP>LEGALFORM</SUB_GROUP>
<KEY>Co. KG</KEY>
<VALUE>OTHER</VALUE>
</row>
</rows>
</resource>
</resources> |
This is the SELECT statement
Quote: |
SET OutputRoot.XMLNSC.rows[] = (SELECT * FROM InputRoot.XMLNSC.resources.resource.rows[] WHERE InputRoot.XMLNSC.resources.resource.name = 'TVPP_ID'); |
This was the OutputRoot.XMLNSC after the SELECT
Code: |
<rows>
<row>
<OASE_ID>0331703945813728346402916</OASE_ID>
<MESSAGE_ID>ID:9eed21fb-f57c-4690-b673-d0f1f08b41dd@JSESSIONID=T1XKS0WDVHQYY7T5WADW6XURQX0Q3LYB.mo11261_b2b1</MESSAGE_ID>
<TRANSACTION_ID>c022c241-96cf-4f70-b5ac-62cf4477136c</TRANSACTION_ID>
<LAST_UPDATED>2013-07-03T11:42:30.420</LAST_UPDATED>
</row>
<row>
<OASE_ID>8888913032100002</OASE_ID>
<MESSAGE_ID>ID:d9b8fde1-7d75-4f6e-acf7-86a0bae56415@JSESSIONID=8QK3X7NOWF0P8EBIOGLSFHBLZL5U3BBX.mo11261_b2b1</MESSAGE_ID>
<TRANSACTION_ID>a3b71450-9f0f-4408-9bac-a5a8963c5e28</TRANSACTION_ID>
<LAST_UPDATED>2013-07-04T09:18:15</LAST_UPDATED>
</row>
</rows> |
Next step was adding a second ESQL node that gets the 2nd XML as input message.
Following ESQL code
Code: |
DECLARE options INTEGER BITOR(FolderBitStream, ValidateContent, ValidateValue);
SET OutputRoot.BLOB.BLOB = ASBITSTREAM(InputRoot.XMLNSC.rows OPTIONS options CCSID 1208); |
Works as expected with this small subtree.
Next step was increasing the number of 'row' childs. I did found that at a certain amount of 'row' childs the OutputRoot.BLOB.BLOB becomes empty.
This the the subtree which causes the empty OutputRoot.BLOB.BLOB
http://catshout.de/output.xml
Best
- Gerald |
|
Back to top |
|
 |
|