Four Stars

tFileOutputXML: generate "File Name" based in value of XML element?

I have a simple job that translates rows in an Excel spreadsheet to XML files (one file for each row):

-----------------------------------

File Excel —- row1 ——> tXMLMap —— outXML ——> tFileOutputXML

-----------------------------------

This works well. The challenge is that I need the XML files produced by tFileOutputXML to be named according to the value in one of the columns from the Excel spreadsheet: row1.DORIGINALFILENAME.

 

I believe I am missing something simple. row1.DORIGINALFILENAME is mapped to an XML element in the tXMLMap. It appears correctly in the XML output.  I’m guessing that there is a way to refer to it in the “File Name” expression on the “Basic settings” tab of tFileOutputXML. I have tried:

————————————————————————

"/Users/bob/Documents/Poc/SampleData/ETL-Output/"+ row1.DORIGINALFILENAME

————————————————————————

 

This produces a set of XML output files named: null0, null1, null2,….

 

I have tried other expression for the “File Name”. None have worked. Is there another method for inserting the value of an XML element in the “File Name” expression within the tFileOutputXML?

 

Thanks,

Bob

 

====================================================

P.S. I have looked for a solution in previous posts to this forum. It appears this is a common pattern. There are OLD post on this forum that define the same issue:

 

1) From 2010: https://www.talendforge.org/forum/viewtopic.php?id=12493

 

The recommended solution here is:

————————————————

Hello 
tMysqlInput---row1-->tFlowToIterate---iterate-->tAdvancedOutputXML

on tFlowToIterate, generate each row.

set the file as:
"..."+row1.id+".xml"

————————————————

 

2) From 2010: https://www.talendforge.org/forum/viewtopic.php?id=12543

 

“PS: I also use this to generate file names: "C:/out-"+(String)globalMap.get("out.Name")+".xml"  .  And always get NULL…”

 

This thread does not have a recommended solution.

13 REPLIES
Twelve Stars TRF
Twelve Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

It should work with this sequence:
tFileInputExcel - tJavaRow -> tXMLMap -> tFileOutputXML
In tJavaRow, generate the code then add the following line to set a global variable based on the DORIGINALFILENAME field:
globalMap.set("xmlFilename", input_row.DORIGINALFILENAME);
In tFileOutputXML reuse this variable as the filename using this expression:
((String)globalMap.get("xmlFilename"))
Hope this helps.

TRF
Four Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

TRF,

 

Your instructions are clear and concise. I believe I followed them correctly. I am now getting the error:

---------------------

org.talend.designer.runprocess.ProcessorException: Job compile errors
At least job "MITRE_ETL_JOB" has a compile errors, please fix and export again.
Error Line: 3173
Detail Message: The method set(String, String) is undefined for the type Map<String,Object>

--------------------

If I comment out the line added to tJavaRow, the error is resolved:

------------------

//globalMap.set("xmlFilename", input_row.DORIGINALFILENAME);

-----------------

Your help is greatly appreciated,

Bob

 

 

Four Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

I changed the globalMap.set() to globalMap.put() according to this forum thread. Now the code runs without error, but I am still getting "null" for the file name when I use the following expression in fFileOutputXML for the "File Name":

-----------

"/Users/bob/Documents/Poc/SampleData/ETL-Output/"+ ((String)globalMap.get("xmlFilename"))+".xml"

-----------

 

Thanks,

Bob

 

Four Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

If I print the globalMap entry immediately after setting it, then I see the value is set correctly:

-----------

globalMap.put("xmlFilename", input_row.DORIGINALNAME);

 

System.out.println((String)globalMap.get("xmlFilename"));

-----------

Prints the correct file name. Something must be happening to the map between the tJavaRow and tFileOutputXML components:

 

FileExcel ---- row1 ---> tJavaRow --- row 2 ---> tXMLMap --- outXML ---> tFileOutputXML

 

Twelve Stars TRF
Twelve Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

You're right for "globalMap.set", I allways make this mistake.
However this doesn't explain the problem you have with value.
Can you share the tFileOutputXML properties?

TRF
Four Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

See attached screenshots for tFileOutputXML settings. The "File Name" is truncated. The full expression is:

------------

"/Users/bob/Documents/Innovators/Poc/SampleData/ETL-Output/"+ ((String)globalMap.get("xmlFilename"))+".xml"

------------

 

Thanks!,

Bob

 

Twelve Stars TRF
Twelve Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

Strange!

Does it come from the option "Split output on several files"?


TRF
Four Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

@TRF Does it come from the option "Split output on several files"?

No. I disabled that and I still get a null value in the output filename from tFileOutputXML. I'm probably doing something stupid.

 

 

Twelve Stars TRF
Twelve Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

Add a tJavaRow just before the tFileOutputXML just to verify the variable is still up to date at this stage?
If it there, it sounds like a bug.
In this case, try to concatenate 2 constant values for the field name (just for checking what's happening).

TRF
Four Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

I added a tJavaRow AFTER the tFileOutputXML and the "xmlFilename" is successfully retrieved from the global map:

((String)globalMap.get("xmlFilename")) 

So there must be some problem with accessing the globalMap within the "File Name" expression of tFileOutputXML!

I stumbled upon Rilhia Solutions tutorial here. Notice section 6: "Output to file (tFileOutputXML)". The default expression from generating the file name is:

context.fileoutputpath+((Integer)globalMap.get("tLoop_1_CURRENT_ITERATION")).intValue()+".xml";

Interesting! They are accessing the globalMap so it must be in scope correctly. There must be a bug in Talend when parsing a user provided expression for "File Name" in tFileOutputXML.

 

Meantime, I tried hacking in different forms of the expression (e.g. single and double escaping the quotes in my globalMap.get() call) to work around the issue. I was not able to guess an alternative form that would parse correctly. Perhaps someone has a suggestion?

 

Thanks,

Bob

 

 

Four Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

Just for fun, I tried accessing the same variable Talend uses in the default file name expression:

 ((String)globalMap.get("tLoop_1_CURRENT_ITERATION")) 

I get null for this as well.

 

I am using DI version 6.4.1

 

Bob

Eight Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

Hi,

 

Could you add a tFlowToIterate and tFixedFlowInput after your tXmlMap ? I tested it and it works fine:

Capture.PNG

 

Capture.PNG

Capture.PNG

 

Eric

 

Eight Stars

Re: tFileOutputXML: generate "File Name" based in value of XML element?

Without tFlowToIterate, the file name of component tFileoutputXML is determined in the first step (Before your tJavaRow code is executed. You can see it setting a breakpoint at these two steps).