freemarker - Retrieve value from sequences - freemarker

Hoping this issue is easy enough to resolve.
I am trying to retrieve a single value from a sequence using FreeMarker via the advanced form PDF functionality in NetSuite.
Here is a snippet of code:
<#assign getOps>
<#list record.item as assembly>
{item: ${assembly.item}, op: ${assembly.operationsequencenumber}}
</#list>
</#assign>
Number of words: ${getOps?word_list?size}
${getOps}
When I print the above, the following is printed:
I want to be able to capture single values from this sequence, using something similar to ${getOps.item} but an error is fired:
For "." left-hand operand: Expected a hash, but this has evaluated to
a string (wrapper: f.t.SimpleScalar):
==> getOps[2] [in template "template" at line 126, column 3]
---- FTL stack trace ("~" means nesting-related):
Failed at: ${getOps[2].item} [in template "template" at line 126, column 1]
Can you identify the issue here?
Any help is appreciated.
Thanks

You are capturing output into a single string there. So it's unstructured, a flat string, therefore you can't traverse it anymore. If you really need to transform the original list, you need to use ?map (see in the FreeMarker Manual). But Netsuite uses a FreeMarker fork, and I'm not sure if they support ?map.

Related

NiFi: change text in FlowFile (Python or ...)

Im very new in NiFi..
I get data(FlowFile ?) from my processor "ConsumerKafka", it seems like
So, i have to delete any text before '!',I know a little Python. So with "ExcecuteScript", i want to do something like this
my_string=session.get()
my_string.split('!')[1]
#it return "ZPLR_CHDN_UPN_ECN....."
but how to do it right?
p.s. or, may be, use "substringAfterLast", but how?
Tnanks.
Update:
I have to remove text between '"Tagname":' and '!', how can i do it without regex?
If you simply want to split on a bang (!) and only keep the text after it, then you could achieve this with a SplitContent configured as:
Byte Sequence Format: Text
Byte Sequence: !
Keep Byte Sequence: false
Follow this with a RouteOnAttribute configured as:
Routing Strategy: Route to Property name
Add a new dynamic property called "substring_after" with a value: ${fragment.index:equals(2)}
For your input, this will produce 2 FlowFiles - one with the substring before ! and one with the substring after !. The first FlowFile (substring before) will route out of the RouteOnAttribute to the unmatched relationship, while the second FlowFile (substring after) will route to a substring_after relationship. You can auto-terminate the unmatched relationship to drop the text you don't want.
There are downsides to this approach though.
Are you guaranteed that there is only ever a single ! in the content? How would you handle multiple?
You are doing a substring on some JSON as raw text. Splitting on ! will result in a "} left at the end of the string.
These look like log entries, you may want to consider looking into ConsumeKafkaRecord and utilising NiFi's Record capabilities to interpret and manipulate the data more intelligently.
On scripting, there are some great cookbooks for learning to script in NiFi, start here: https://community.cloudera.com/t5/Community-Articles/ExecuteScript-Cookbook-part-1/ta-p/248922
Edit:
Given your update, I would use UpdateRecord with a JSON Reader and Writer, and Replacement Value Strategy set to Record Path Value .
This uses the RecordPath syntax to perform transformations on data within Records. Your JSON Object is a Record. This would allow you to have multiple Records within the same FlowFile (rather than 1 line per FlowFile).
Then, add a dynamic property to the UpdateRecord with:
Name: /Tagname
Value: substringAfter(/Tagname, '!' )
What is this doing?
The Name of the property (/Tagname) is a RecordPath to the Tagname key in your JSON. This tells UpdateRecord where to put the result. In your case, we're replacing the value of an existing key (but it could be also be a new key if you wanted to add one).
The Value of the property is the expression to evaluate to build the value you want to insert. We are using the substringAfter function, which takes 2 parameters. The first parameter is the RecordPath to the Key in the Record that contains the input String, which is also /Tagname (we're replacing the value of Tagname, with a substring of the original Tagname value). The second parameter is the String to split on, which is !.
If your purpose getting the string between ! and "} use ReplaceText with (.*)!(.*)"} , capture second group and replace it with entire content
Please note that this regular expression may not be best for your case but I believe you can find solution for your problem with regular expression

Length of Assign variable issue in freemarker

I am using freemarker ..want to find the length of assign variable ..i used size and length function ..but it fails and returns the error ..Please help me in how to find length of the assign variable
Please find the below code i have tried...
Input data --- cusID="a-1242" -- I want to split input data by - and want to store in separate variable through assign function
<#list (it.#CusID[0]!"")?split("-") as c><#if ((c?index) ==0)>
<#assign first>${c}</#assign>
<#assign firstlen = c?size>
</#if>
</#list>
Above code firstlen is used to find the length but it fails to find length
ERROR MESSAGES find below
For "?size" left-hand operand: Expected an extended-hash or sequence
or extended collection, but this has evaluated to a markup_output
(wrapper: f.c.TemplateXMLOutputModel):
As the error message says, first stores XML markup, not just a plain text string. You can't get the length of markup with ?length, as it's not obvious what that means (like if the content of which XML elements matter, what if you have an entity reference, etc.). The reason it's markup is that <#assign first>...</#assign> is not a normal assignment, it's for capturing output, and you are using XML output format. Instead, use normal value assignment: <#assign first = c>. Now first will have the same type as c, string.

Getting "XPath error: Invalid predicate", while trying to use an Xpath that contains greek letters

From this webpage: page I am trying to build a crawler that is going to extract "Μακεδονία > Ν. Ημαθίας > Δ. Δοβρά" from the "Περιοχή:" field.
--> See a screenshot of the item:
See Link no.2 below
In order to do this, I am intended to use XPath to focus on "Περιοχή:" and then use the following-sibling keyword to access and extract the text "Μακεδονία > Ν. Ημαθίας > Δ. Δοβρά", because the td that contains it can be in a different location in other webpages (but always after the tr with the text "Περιοχή:") or even missing.
See Link no.3 below
In scrapy shell I am testing the following:
x = response.xpath(u"//th[#text()=u'Περιοχή:']/text()").extract()
expecting to get x = [u"Περιοχή:"]
but instead I am getting an error:
ValueError: XPath error: Invalid predicate in //th[#text()=u'\u03a0\u03b5\u03c1\u03b9\u03bf\u03c7\u03ae:']/text()
What am I doing wrong?
Thanks in advance.
You are specifying unicode encoding twice, you shouldn't specify that in xpath since it's already an unicode string.
i.e.
# this:
u"//th[#text()=u'Περιοχή:']/text()"
# should be this:
u"//th[text()='Περιοχή:']/text()"
Notice no u before the text and you don't need # before text() either because it's an xpath function not a node attribute.

Can't YAML::load an YAML:dumped XML value

When trying to YAML::load a value produced by YAML::dump I get an error "did not find expected key while parsing a block mapping at line 1 column 1"
The YAML::dump value was written to an XML file as:
<format_store>---:text_formatting: '':url_pattern: ''</format_store>
If I look into the database, it is a text field with line breaks in it.
---
:text_formatting: ''
:url_pattern: ''
So it looks like the conversion from YAML::dump into the XML format dropped the line breaks.
I explicitly use the YAML::dump format for text fields. XML does not allow line breaks in element values. It would have to be escaped in some way and I assumed YAML would take care of that.
Is there a better way to dump/load text fields or is there someting I'm missing here?
Option 1: Wrap the YAML content in a <![CDATA]]> as suggested in Adding a new line/break tag in XML.
Option 2: Configure your YAML library to dump mappings using flow style (e.g {':text_formatting' : '', ':url_pattern' : ''). The exact method for accomplishing this will depend on the YAML library you are using and may require a bit of custom coding.

JMeter XPath Extractor SAXException

I am using xpath extractor to retrieve a form attribute value from the response data. However, this response data contains, among other data the String "C&I", and this is causing the following SAXException
jmeter.extractor.XPathExtractor: SAXException while processing
(substring-after(//form[#id='headerForm']/#action,'/dashboard.xhtml?'))
The reference to entity "I" must end with the ';' delimiter.
I do not have any control over this data since it is being obtained from the database. I tried checking the "Use Tidy(tolerant parser)" option. That results in the following warning/error
ERROR - jmeter.util.XPathUtil: TidyException: line 35 column 31 -
Warning: trimming empty <div>
Line 35 of the response is as follows:
`<div style="clear: both;"></div>`
Extracting that attribute value is essential for further processing for me.
As for everything there is solution, it might be quick and dirty but there is always more solutions to a single problem.
I recommend using jsoup to do the parsing of HTML for you instead of xpath extractor. I'm assuming you're trying to extract the particular forms' action attribute.
Step 1 -> Add jsoup-1.6.3.jar or any other version to your JMETER_HOME\lib
Step 2 -> Add a BeanShell PostProcessor to your Sampler HTTP or any other
Step 3 -> In a Script big box paste this code :
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
String html = prev.getResponseDataAsString(); // get response from your sampler
Document doc = Jsoup.parse(html);
String formAction = doc.select("#headerForm").attr("action");
vars.put("action", formAction);
HTML selectors are jquery based. So it can do pretty nice and neat things. Anyway you should have ${action} variable to use further in your tests.
Update
So you don't get tangled with the code I've created jMeter post processor called Html Extractor here is the github url :
https://github.com/c0mrade/Html-Extractor
The stray & in your source document is not legal in XML. From the XML spec (emphasis mine)
The ampersand character (&) and the left angle bracket (<) may appear
in their literal form only when used as markup delimiters, or within a
comment, a processing instruction, or a CDATA section. They are also
legal within the literal entity value of an internal entity
declaration; see "4.3.2 Well-Formed Parsed Entities". If they are
needed elsewhere, they must be escaped using either numeric character
references or the strings "&" and "<" respectively.
The parser is interpreting the & as the start of an entity reference, which it expects to end with a semicolon.
Source:
http://www.w3.org/TR/1998/REC-xml-19980210/#syntax
Note that the error you've included is (almost certainly) unrelated. Tidy is merely pointing out that the div contains no content (i.e. it's empty).

Resources