How to replace every occurrence of a string in dataSetRow? - birt

I have some very large rptdesign report definition files.
I would like to do something like in the example below:
<expression name="expression">dataSetRow["WORK_DESCRIPTION"].replace(new RegExp('&lt;', 'g'), '<');</expression>
But for any occurrence of string in any dataset in any cell in any row.
Is this possible to do in rptdesign?
Or is there other way to accomplish this task?

One way you could do this is to create a style (use predefined data style) and add a map to it. Put a script in first expression like:
importPackage(Packages.java.lang);
if( _jsContext.getContent().getValue() instanceof String ){
if( _jsContext.getContent().getValue() == "S18_1749" ){
_jsContext.getContent().setValue(_jsContext.getContent().getValue()+"--");
}
}
true;
This will always return true. Set the second expression to false, so the map never occurs. It is a bit ugl

Related

xpath: check if current elements position is second in order

Background:
I have an XML document with the following structure:
<body>
<section>content</section>
<section>content</section>
<section>content</section>
<section>content</section>
</body>
Using xpath I want to check if a <section> element is the second element and if so apply some function.
Question:
How do I check if a <section> element is the second element in the body element?
../section[position()=2]
If you want to know if the second element in the body is named section then you can do this:
local-name(/body/child::element()[2]) eq "section"
That will return either true or false.
However, you then asked how can you check this and if it is true, then apply some function. In XPath you cannot author your own functions you can only do that in XQuery or XSLT. So let me for a moment assume you are wishing to call a different XPath function on the value of the second element if it is a section. Here is an example of applying the lower-case function:
if(local-name(/body/child::element()[2]) eq "section")then
lower-case(/body/child::element()[2])
else()
However, this can simplified as lower-case and many other functions take a value with a minimum cardinality of zero. This means that you can just apply the function to a path expression, and if the path did not match anything then the function typically returns an empty sequence, in the same way as a path that did not match will. So, this is semantically equivalent to the above:
lower-case(/body/child::element()[2][local-name(.) eq "section"])
If you are in XQuery or XSLT and are writing your own functions, I would encourage you to write functions that will accept a minimum cardinality of zero, just like lower-case does. By doing this you can chain functions together, and if there is no input data (i.e. from a path expression that does not match anything), these is no output data. This leads to a very nice functional programming style.
Question: How do I check if a element is the second element
in the body element?
Using C#, you can utilize theXPathNodeIterator class in order to traverse the nodes data, and use its CurrentPosition property to investigate the current node position:
XPathNodeIterator.CurrentPosition
Example:
const string xmlStr = #"<body>
<section>1</section>
<section>2</section>
<section>3</section>
<section>4</section>
</body>";
using (var stream = new StringReader(xmlStr))
{
var document = new XPathDocument(stream);
XPathNavigator navigator = document.CreateNavigator();
XPathNodeIterator nodes = navigator.Select("/body/section");
if (nodes.MoveNext())
{
XPathNavigator nodesNavigator = nodes.Current;
XPathNodeIterator nodesText =
nodesNavigator.SelectDescendants(XPathNodeType.Text, false);
while (nodesText.MoveNext())
{
if (nodesText.CurrentPosition == 2)
{
//DO SOMETHING WITH THE VALUE AT THIS POSITION
var currentValue = nodesText.Current.Value;
}
}
}
}

Format Output of Placeholder

I am creating a dynamic list of placeholders, some of the values held in these place holders are decimal numbers that are supposed to represent money.
What I'm wondering is if there is a way I can format them to display as such?
Something like [[+MoneyField:formatmoney]]
I see http://rtfm.modx.com/revolution/2.x/making-sites-with-modx/customizing-content/input-and-output-filters-(output-modifiers) but I do not see a way to do this here.
You most definitely can, under the header "Creating a Custom Output Modifier" on the link you posted it's described how you can place a snippet name as a output modifier. This snippet will recieve the [[+MoneyField]] value in a variable called $input.
So you'd have to create this custom snippet which could be as simple as
return '$'.number_format($input);
Another version of doing this is calling the snippet directly instead of as an output modifier like so:
[[your_custom_money_format_snippet ? input=`[[+MoneyField]]`]]
I'm not sure if theres any difference between the two in this case. Obviously you can pass any value into the number format snippet when calling it as a snippet instead of an output modifier. And i'm sure theres a microsecond of performance difference in the two but i'm afraid i don't know which one would win. ;)
Update:
Actually found the exact example you want to implement on this link;
http://rtfm.modx.com/revolution/2.x/making-sites-with-modx/customizing-content/input-and-output-filters-%28output-modifiers%29/custom-output-filter-examples
Snippet:
<?php
$number = floatval($input);
$optionsXpld = #explode('&', $options);
$optionsArray = array();
foreach ($optionsXpld as $xpld) {
$params = #explode('=', $xpld);
array_walk($params, create_function('&$v', '$v = trim($v);'));
if (isset($params[1])) {
$optionsArray[$params[0]] = $params[1];
} else {
$optionsArray[$params[0]] = '';
}
}
$decimals = isset($optionsArray['decimals']) ? $optionsArray['decimals'] : null;
$dec_point = isset($optionsArray['dec_point']) ? $optionsArray['dec_point'] : null;
$thousands_sep = isset($optionsArray['thousands_sep']) ? $optionsArray['thousands_sep'] : null;
$output = number_format($number, $decimals, $dec_point, $thousands_sep);
return $output;
Used as output modifier:
[[+price:numberformat=`&decimals=2&dec_point=,&thousands_sep=.`]]

How to extract token information from attribute "elements"?

1. Overall Task:
I want to customize the Java.stg to modify the token display format in the comment of the code block for an alternative of grammar rule.
2. Context:
one rule in my current grammar is:
temporal returns [String ret]:
NEXT disj
{$ret= $ret= "X ".concat($disj.ret);}
| EVENTUALLY disj
{$ret= "F ".concat($disj.ret);}`
;
The corresponding generated code block (in parser) is as follows:
switch (alt2) {
case 1 :
// RERS.g:26:7: NEXT disj
{
match(input,NEXT,FOLLOW_NEXT_in_temporal204);
pushFollow(FOLLOW_disj_in_temporal206);
disj2=disj();
state._fsp--;
ret = ret = "X ".concat(disj2);
}
break;
case 2 :
// RERS.g:28:7: EVENTUALLY disj
{
match(input,EVENTUALLY,FOLLOW_EVENTUALLY_in_temporal222);
pushFollow(FOLLOW_disj_in_temporal224);
disj3=disj();
state._fsp--;
ret = "F ".concat(disj3);
}
break;
3. My Goal:
Change the comment from format like // RERS.g:26:7: NEXT disj to NEXT_disj, i.e., from <fileName>:<description> to <MyOwnAttribute>
4. Attempt so far:
I tried to modify the template "alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew)" as follows:
alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew) ::= <<
/* <elements:ExtractToken()> */
{
<#declarations()>
<elements:element()> // as I understand, it's just an template expansion to apply the sub templates in each elements
<rew>
<#cleanup()>
}
>>
I checked that in this context, the value of attribute elements is something like {el=/tokenRef(), line=26, pos=7}{el=/ruleRef(), line=26, pos=12}{el=/execAction(), line=27, pos=7}.
I think I should "overload" the "tokenRef" template to spit out tokens formatted like "NEXT_disj"
5. Questions:
How to "overload" an existing template? I want to do that because I will have to modify the value of "elements" otherwise.
How can I only apply a template to a specific element in attribute "elements", instead of applying it to every element (like what template "element()" does)?
I think there should be some convenient way to achieve my goal. Any suggestion?
Thanks in advance.

T4 FieldName in camelCase without Underscore?

I'm using T4 to generate some class definitions and find that I'm getting an underscore in front of my field names.
I have set
code.CamelCaseFields = true;
just to be safe (even though I understand that's the default) but still end up with _myField rather than myField.
How can I generate a field name without the '_' character?
Also, where is the documentation for T4? I'm finding plenty of resources such as
Code Generation and Text Templates and numerous blogs, but I have not found the class-by-class, property-by-property documentation.
You're probably talking about EF4 Self Tracking Entities. The CodeGenerationTools class is included via the <## include file="EF.Utility.CS.ttinclude"#> directive, which you can find at "[VSInstallDir]\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes\EF.Utility.CS.ttinclude".
The FieldName function is defined as such:
private string FieldName(string name)
{
if (CamelCaseFields)
{
return "_" + CamelCase(name);
}
else
{
return "_" + name;
}
}
The "_" is hardcoded in the function. Coding your own shouldn't be difficult. Note that the CodeGenerationTools class is specific to this ttinclude file and isn't a generic and embedded way to generate code in T4.
I've written the following method to make first character upper case, remove spaces/underscores and make next character upper case. See samples below. Feel free to use.
private string CodeName(string name)
{
name = name.ToLowerInvariant();
string result = name;
bool upperCase = false;
result = string.Empty;
for (int i = 0; i < name.Length; i++)
{
if (name[i] == ' ' || name[i] == '_')
{
upperCase = true;
}
else
{
if (i == 0 || upperCase)
{
result += name[i].ToString().ToUpperInvariant();
upperCase = false;
}
else
{
result += name[i];
}
}
}
return result;
}
input/output samples:
first_name = FirstName,
id = Id,
status message = StatusMessage
This is good advice however it doesn't help you in knowing WHERE the right place to put such a function is...
Is there any guidance on DECOMPOSING the EF .tt files or stepping through the output generation to see how it builds the output?
I was able to use the above function successfully by plugging it into a function called
(Ef4.3)
public string Property(EdmProperty edmProperty)
Which appears to be used to output the lines like "public int fieldname { get; set; }"
and changed the 3rd (index {2}) param to the formating to wrap with the function to modify the name, like this:
_typeMapper.GetTypeName(edmProperty.TypeUsage), //unchanged
UnderScoreToPascalCase(_code.Escape(edmProperty)), //wrapped "name"
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)), // unchanged
This is not perfect, eg: it doesn't keep existing "Ucasing" and doesn't care about things like this:
customerIP
outputs: Customerip
which IMO is not very readable...
but its better than what I WAS looking at which was a nightmare because the database was intermingled mess of camelCase, PascalCase and underscore separation, so pretty horrific.
anyway hope this helps someone...

Codeigniter: URI segments

How do I create an if statement saying something like this?
Basically, how do you use the URI class to determine if there is a value in any segment?
$segment = value_of_any_segment;
if($segment == 1{
do stuff
}
I know this is pretty elementary, but I don't totally understand the URI class...
Your question is a little unclear to me, but I'll try to help. Are you wondering how to determine if a particular segment exists or if it contains a specific value?
As you are probably aware, you can use the URI class to access the specific URI segments. Using yoursite.com/blog/article/123 as an example, blog is the 1st segment, article is the 2nd segment, and 123 is the 3rd segment. You access each using $this->uri->segment(n)
You then can construct if statements like this:
// if segment 2 exists ("articles" in the above example), do stuff
if ($this->uri->segment(2)) {
// do stuff
}
// if segment 3 ("123" in the above example) is equal to some value, do stuff
if ($this->uri->segment(3) == $myValue) {
// do stuff
}
Hope that helps! Let me know if not and I can elaborate or provide additional information.
Edit:
If you need to determine if a particular string appears in any segment of the URI, you can do something like this:
// get the entire URI (using our example above, this is "/blog/article/123")
$myURI = $this->uri->uri_string()
// the string we want to check the URI for
$myString = "article";
// use strpos() to search the entire URI for $myString
// also, notice we're using the "!==" operator here; see note below
if (strpos($myURI, $myString) !== FALSE) {
// "article" exists in the URI
} else {
// "article" does not exist in the URI
}
A note regarding strpos() (from the PHP documentation):
This function may return Boolean
FALSE, but may also return a
non-Boolean value which evaluates to
FALSE, such as 0 or "". Please read
the section on Booleans for more
information. Use the === operator for
testing the return value of this
function.
I hope my edit helps. Let me know if I can elaborate.

Resources