talend thmap get value of outer loop element - talend

I'm just starting out with thMap.
So far I have successfully mapped an X12 835 message to output structures. That works no problem.
I have also successfully acquired the LoopIndex of the current loop using the LoopIndex() function.
My challenge:
I need to get the value of an element from the enclosing loop.
In the attached image, everything in green is working.
I'm trying to get the value down the red line.
My goal is to do this assignment
gsRecord.parent_id = enclosing loop isaRecord.id
The documentation explains some things but I don't see examples putting it together.
Does anyone have any good examples, videos or suggestions?
Update from 12/9/22
Here is something I have tried. Providing this example in hopes someone recognizes a specific issue to help move me forward. Any input would be appreciated.
Per this screenshot
I am attempting to output in gsRecord.parent_id the loopIndex of the parent loop (isaRecord).
This gives me the following error
"An reference in an LoopIndex/Variable was made to an either an input
map element or an output map element that is not in the context of the
reference. Use an enclosing looping output map element here.(msg #1202)"
Given the reference to 'enclosing looping output map element here' it feels like the gsRecord is not properly defined as a child of the isaRecord.
However the definition of the gsRecord is in reference to the isaRecord as in this screenshot.
It feels like there is some combination of LoopIndex and EnclosedContext that I could use to accomplish this but I'm unable to find any in-depth documentation on the functions.
Any help would be appreciated.

Related

How do I find the index of a json object in an array based off of a value of its properties

I am fairly new to Redis and RedisJson and I have been through all the documentation I can get my hands on, but I still can't seem to figure this one out. I am hoping someone could shed some light on this situation to help me understand. My end goal is to be able to remove the JSON object from the responses array using JSON.ARRPOP. I need to get the index of the object first and I can't seem to do that.
Here is my object structure:
JSON.SET test:1 $ '{ "responses":[{"responseId":"29aab59c-10b0-48c0-ab91-8873fb6e2238"},{"responseId":"ab79f09b-8e31-41f4-9191-ef89a34964d3"}]}'
Check the path:
JSON.GET test:1 $.responses[*].responseId
RETURNS:
"["29aab59c-10b0-48c0-ab91-8873fb6e2238","ab79f09b-8e31-41f4-9191-ef89a34964d3"]"
Ok looks good I have an array of two strings lets get that index of 29aab59c-10b0-48c0-ab91-8873fb6e2238.
JSON.ARRINDEX test:1 $.responses[*].responseId '"29aab59c-10b0-48c0-ab91-8873fb6e2238"'
RETURNS:
(nil)
(nil)
It appears to have searched but found nothing?
At first I thought it was an escape character issue but I get the same results with responeIds as integers 1 and 2.
Any help here would be greatly appreciated. Thanks!
JSON.ARRINDEX can only search for scalar values. Objects and arrays are not scalars so you can't search for them.
For your use case you should look at https://redis.io/docs/stack/search/indexing_json/

Parsing XML and retrieving attributes from (nested?) elements

I am trying to get specific data from an XML file, namely X, Y coordinates that are appear, to my beginners eyes, attributes of an element called "Point" in my file. I cannot get to that data with anything other than a sledgehammer approach and would gratefully accept some help.
I have used the following successfully:
for Shooter in root.iter('Shooter'):
print(Shooter.attrib)
But if I try the same with "Point" (or "Points") there is no output. I cannot even see "Point" when I use the following:
for child in root:
print(child.tag, child.attrib)
So: the sledgehammer
print([elem.attrib for elem in root.iter()])
Which gives me the attributes for every element. This file is a single collection of data and could contain hundreds of data points and so I would rather try to be a little more subtle and home in on exactly what I need.
My XML file
https://pastebin.com/abQT3t9k
UPDATE: Thanks for the answers so far. I tried the solution posted and ended up with 7000 lines of which wasn't quite what I was after. I should have explained in more detail. I also tried (as suggested)
def find_rec(node, element, result):
for item in node.findall(element):
result.append(item)
find_rec(item, element, result)
return result
print(find_rec(ET.parse(filepath_1), 'Shooter', [])) #Returns <Element 'Shooter' at 0x125b0f958>
print(find_rec(ET.parse(filepath_1), 'Point', [])) #Returns None
I admit I have never worked with XML files before, and I am new to Python (but enjoying it). I wanted to get the solution myself but I have spent days getting nowhere.
I perhaps should have just asked from the beginning how to extract the XY data for each ShotNbr (in this file there is just one) but I didn't want code written for me.
I've managed to get the XY from this file but my code will never work if there is more than one shot, or if I want to specifically look at, say, shot number 20.
How can I find shot number 2 (ShotNbr="2") and extract only its XY data points?
Assuming that you are using:
xml.etree.ElementTree,
You are only looking at the direct children of root.
You need to recurse into the tree to access elements lower in the hierarchical tree.
This seems to be the same problem as ElementTree - findall to recursively select all child elements
which has an excellent answer that I am not going to plagiarize.
Just apply it.
Alternatively,
import xml.etree.ElementTree as ET
root = ET.parse("file.xml")
print root.findall('.//Point')
Should work.
See: https://docs.python.org/2/library/xml.etree.elementtree.html#supported-xpath-syntax

Two-sided references in a list

I'm just starting to learn Perl and I have to do an exercise containing references.
I have to create a program, that constructs a list with two sided references, that are are received as command line arguments. At the beginning of the program, there is only one element in the list - 0. To go through the list, reference is being used, that references to the only element of the list at the moment - 0. The arguments of the command line are being read one by one and added right behind the element, that is being referenced to. When one argument is added, the reference slides one element to the right(it references to the newly added element). There are also two special elements - + and -. + allows the reference to move one element to the right, and - one element to the left. Also, it is important that the reference would not go beyond the list limit.
The output is all the arguments in the correct order of the list.
Additional requirements are that the list must be created by using hashes, that contain links to neighbouring elements. Also, I cannot use arrays to store the whole list.
There are a few examples to make it easier to grasp the concept, this is the most useful one:
./3.pl A D - B C + E
0 A B C D E
All I've got now is just the start of the program, it is nowhere near done and doesn't compile, but I can't figure out where to go from there. I've tried looking for some information about two-sided references(I'm not sure if I'm translating it correctly), but I can't seem to find anything. Any information about two-sided references or any tips how to start writing this program properly would be very appreciated.
My code:
#!/usr/bin/perl
use strict;
use warnings;
my $A= {
value=>'0',
prev=>'undef',
next=>'$B'
};
my $B= {
value=>'0',
prev=>'$A',
next=>'$C'
};
my $C= {
value=>'0',
prev=>'$B',
next=>'undef'
};
for my $smbl(0..#$ARGV) {
$A-> {value} = $ARGV[$smbl];
$Α-> {next} = $ARGV[$smbl+1];
}
First of all, what you are building is called a doubly linked list.
Let me tell you the biggest trick for working with linked lists: Create a dummy "head" node and a dummy "tail" node. You won't print their values, but having them will greatly reduce the number of special cases in your code, making it so much simpler!
At the core, you will have three "pointers" (references).
$head points to the first node of the list.
$tail points to the last node of the list.
$cursor initially points to the node in $tail. New nodes will be inserted before this node.
When processing +, two different situations you need to handle:
$cursor == $tail: Error! Cursor moved beyond end of list.
$cursor != $tail: Point $cursor to the node following the one it references.
When processing -, there are two different situations you need to handle:
$cursor->{prev} == $head: Error! Cursor moved beyond start of list.
$cursor->{prev} != $head: Point $cursor to the node preceding the one it references.
When processing inserting nodes, no checks need to be performed because of the dummy nodes!

Debugging a for loop in matlab

I've been looking throught the documentation, but can't seem to find the bit I want.
I have a for loop and I would like to be able to view every value in the for loop.
for example here is a part of my code:
for d = 1 : nb
%for loop performs blade by blade averaging and produces a column vector
for cc = navg : length(atbmat);
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg;
atbvec2(:,cc) = atb2;
end
%assigns column vector 'atbvec2' to the correct column of the matrix 'atbmat2'
atbmat2(d,1:length(atbvec2)) = atbvec2;
end
I would like to view every value of atb2. I'm a python user(new to MATLAB) and would normally use a simple print statement to find this.
I'm sure there is a way to do it, but I can't quite find how.
Thankyou in advance.
you can use disp in Matlab to print to the screen but you might want to use sprintf first to format it nicely. However for debugging you're better off using a break point and then inspect the variable in the workspace browser graphically. To me, this is one of Matlab's best features.
Have a look at the "Examine Values" section of this article
The simplest way to view it everywhere is to change this line:
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg;
Into this, without semicolon:
atb2 = (sum(atbmat((cc-(navg-1):cc),d)))/navg
That being said, given the nature of your calculation, you could get the information you need as well by simply storing every value of abt2 and observing them afterwards. This may be done in atbmat2 already?
If you want to look at each value at the time it happens, consider setting a breakpoint or conditional breakpoint after the line where abt2 is assigned.

Webdriver kicks the bucket on "find_element"

I am using the Ruby interpretation of Webdriver. Now the webpage I am looking at may or may not contain a certain element. If it doesn't I would like to look for another element. However, whenever Webdriver can't find an element it throws an exception.
My question is, can I check to see if the element even exists on the page without littering my code with begin/rescue blocks ?
Any help is greatly appreciated.
The short answer is no. To check if element exists, you have to rescue errors. find_element always throw NoSuchElementError if element was not found. You can for example take a look at implementation of #exists? method in Watir-WebDriver.
Still, you can use find_elements method which will return empty array if not elements were found.
elements = #browser.find_elements(id: 'doesnt-exist')
if elements.empty?
# go to the next element
else
# work with element
element = elements.first
element.click
end