Calculations inside a repeater (new repeat) control - xpath

A form in a Orbeon form builder contains a repeater control(new repeat).Suppose there are three text controls on each row(or repeat) of a repeater control(new repeat).first two text controls on each row contains numeric values.I want to bring the product of first two text controls to the third text control at run time without any event.there will be multiple numbers of repeat in the runtime ,i.e the row may increase but for each the calculation much reflect at runtime and for each row product of first two must be viewed on the third one
I used the following codes :
if ($quantity castable as xs:double and $price castable as xs:double)
then $quantity * $price
else 'n/a'
Its ok with this xpath expression when there is only one row in the repeater control.But on adding new rows ,i.e on increasing the repeat at run time, all results in the controls of third column changes to the else value ("n/a"). This is working only for a single row of a repeater control(new repeat). Because for every repeat the value must be calculated for each row separately.

Assume this is your node which repeats for each row
<repeater>
<quantity></quantity>
<price></price>
<product></product>
</repeater>
the Xpath expression for calculating the product would be
if(../quantity castable as xs:double and ../price castable as xs:double)
then ../quantity * ../price
else 'N/A'
This expression when used in calculate for the <product> node results the product on each row and there is no event based action required since this is written on the bind definition of the node.
Hope this answers to all your questions

Related

How to add an array formula for updates

I'm working on trying to add an array formula so that the status column updates as information is entered.
This is an order tracking sheet. When an order is entered get set to Available, Once a driver is assigned change the status to Dispatched. As times are entered in the In and Out columns to change from Picked to Delivered. Finally once its checked off as Billed to mark the status as Complete.
So far I've only gotten to
=ARRAYFORMULA(IF(LEN(D3:D&H3:H&I3:I&M3:M&N3:N)=0, "Available", IF(D3:D<>"", "Dispatched")))
I haven't been able to figure out past that.
https://docs.google.com/spreadsheets/d/13tOkLwtPYyWm9rUfkCidqwUygzFfVfmIzV-EwL5i7hM/edit?usp=sharing
I wasn't sure which column was used to mark billed, so I just guess column P, just change it to the proper column. Enter this formula in row 1 of your status column.
={"Status";
ARRAYFORMULA(
IFERROR(
IFS(
P2:P<>"", "Complete",
J2:J<>"", "Delivered",
I2:I<>"", "Picked",
E2:E<>"", "Dispatched"
),
"")
)}
Explanation
Starting inside and working out:
The ranges J2:J, etc, tell the array formula which column to evaluate as it goes row by row, starting at row 2, and ending at the bottom of the sheet.
The IFS formula checks condition:result pairs, If the first condition is met, it displays that value, but if not, it goes to the next one, and so on until it finds a condition that is true or reaches the end.
The IFS formula will return an error if it doesn't find any of the conditions to be true, so the IFERROR says to leave the cell blank if there are no true conditions.
The ARRAYFORMULA evaluates each row for the defined range.
The { xxxx ; xxxxxxx}stacks the items after the semicolon below the item before the semicolon. In this usage, the label "Status" is in row 1, and the results are in the rows below it. This ensures that no one accidentally sorts or erases the formula.

AddField function does not work as expected

I have the following block of code that iterates through the fields of each table and adds the fields of the current table respectively in order to create a number of tableboxes.
'iterate through every table
For i=1 To arrTCount
'the arrFF array holds the names of the fields of each table
arrFF = Split(arrFields(i), ", ")
arrFFCount = UBound(arrFF)
'create a tablebox
Set TB = ActiveDocument.Sheets("Main").CreateTableBox
'iterate through the fields of the array
For j=0 to (arrFFCount - 1)
'add the field to the tablebox
TB.AddField arrFF(j)
'Msgbox(arrFF(j))
Next
Set tboxprop = TB.GetProperties
tboxprop.Layout.Frame.ObjectId = "TB" + CStr(i)
TB.SetProperties tboxprop
Next
The above code creates the tableboxes, but with one field less every time (the last one is missing). If I change the For loop from For j=0 To (arrFFCount - 1) to For j=0 To (arrFFCount) it creates empty tableboxes and seems to execute forever. Regarding this change, I tested the field names with the Msgbox(arrFF(j)) command and it shows me the correct field names as I want them to be in the tableboxes in the UI of QlikView.
Does anybody have an idea of what seems to be the problem here? Can I do this in a different way?
To clarify the situation here and what I have tested so far, I have 11 tables to make tableboxes of and I have tried with just one of them or some of them. The result I am seeing with the code is on the left and what I am expecting to see is on the right of the following image. Please note that the number of fields vary for each table and the image has just one of them as an example.

How can I locate items using xpath from below elements?

I've created some xpath expressions to locate the first item by it's "index" after "h4". However, I did something wrong that is why it doesn't work at all. I expect someone to take a look into it and give me a workaround.
I tried with:
//div[#id="schoolDetail"][1]/text() --For the Name
//div[#id="schoolDetail"]//br[0]/text() --For the PO Box
Elements within which items I would like the expression to locate is pasted below:
<div id="schoolDetail" style=""><h4>School Detail: Click here to go back to list</h4> GOLD DUST FLYING SERVICE, INC.<br>PO Box 75<br><br>TALLADEGA AL 36260<br> <br>Airport: TALLADEGA MUNICIPAL (ASN)<br>Manager: JEAN WAGNON<br>Phone: 2563620895<br>Email: golddustflyingse#bellsouth.net<br>Web: <br><br>View in AOPA Airports (Opens in new tab) <br><br></div>
By the way, the resulting values should be:
GOLD DUST FLYING SERVICE, INC.
PO Box 75
Try to locate required text nodes by appropriate index:
//div[#id="schoolDetail"]/text()[1] // For "GOLD DUST FLYING SERVICE, INC."
//div[#id="schoolDetail"]/text()[2] // For "PO Box 75"
Locator to get both elements:
//*[#id='schoolDetail']/text()[position()<3]
Explanation:
[x] - xPath could sort values using predicate in square brackets.
x - could be integer, in this case it will automatically be compared with element's position in this way [position()=x]:
//div[2] - searches for 2nd div, similar to div[position()=2]
In case predicate [x] is not an integer - it will be automatically converted to boolean value and will return only elements, where result of x is true, for example:
div[position() <= 4] - search for first four div elements, as 4 <= 4, but on the 5th and above element position will be more than 4
Important: please check following locators on this page:
https://www.w3schools.com/tags/ref_httpmessages.asp
//table//tr[1] - will return every 1st row in each table ! (12 found
elements, same as tables on the page)
(//table//tr)[1] - will return 1st row in the first found table (1 found element)

Visual Basic Function Procedure

I need help with the following H.W. problem. I have done everything except the instructions I numbered. Please help!
A furniture manufacturer makes two types of furniture—chairs and sofas.
The cost per chair is $350, the cost per sofa is $925, and the sales tax rate is 5%.
Write a Visual Basic program to create an invoice form for an order.
After the data on the left side of the form are entered, the user can display an invoice in a list box by pressing the Process Order button.
The user can click on the Clear Order Form button to clear all text boxes and the list box, and can click on the Quit button to exit the program.
The invoice number consists of the capitalized first two letters of the customer’s last name, followed by the last four digits of the zip code.
The customer name is input with the last name first, followed by a comma, a space, and the first name. However, the name is displayed in the invoice in the proper order.
The generation of the invoice number and the reordering of the first and last names should be carried out by Function procedures.
Seeing as this is homework and you haven't provided any code to show what effort you have made on your own, I'm not going to provide any specific answers, but hopefully I will try to point you in the right direction.
Your first 2 numbered items look to be variations on the same theme... string manipulation. Assuming you have the customer's address information from the order form, you just need to write 2 separate function to take the parts of the name and address, take the data you need and return the value (which covers your 3rd item).
To get parts of the name and address to generate the invoice number, you need to think about using the Left() and Right() functions.
Something like:
Dim first as String, last as String, word as String
word = "Foo"
first = Left(word, 1)
last = Right(word, 1)
Debug.Print(first) 'prints "F"
Debug.Print(last) 'prints "o"
Once you get the parts you need, then you just need to worry about joining the parts together in the order you want. The concatenation operator for strings is &. So using the above example, it would go something like:
Dim concat as String
concat = first & last
Debug.Print(concat) 'prints "Fo"
Your final item, using a Function procedure to generate the desired values, is very easily google-able (is that even a word). The syntax is very simple, so here's a quick example of a common function that is not built into VB6:
Private Function IsOdd(value as Integer) As Boolean
If (value Mod 2) = 0 Then 'determines of value is an odd or even by checking
' if the value divided by 2 has a remainder or not
' (aka Mod operator)
IsOdd = False ' if remainder is 0, set IsOdd to False
Else
IsOdd = True ' otherwise set IsOdd to True
End If
End Function
Hopefully this gets you going in the right direction.

How do I select sets of nodes with a single XPath query?

I'm trying to extract journey and price information from my favorite airline.
I have a search results page that looks like this:
MASwings search results http://img28.imagevenue.com/aAfkjfp01fo1i-2846/loc29/42467_dayview_oneway_122_29lo.jpg
EDIT: Image host might have blocked the hotlink. See the image on this page: http://img28.imagevenue.com/img.php?image=42467_dayview_oneway_122_29lo.jpg
Repro URL for booking query
I can select each row that represents a flight using this XPath selector:
//*[#class="servicecode "]/ancestor::tr[1]
But each flight row is not an independent journey; the flights are really grouped into legs, and these are what I want to select.
The row class alternates for each new leg: the rows of the first leg have class "datarow", and the rows of the next leg have "datarow alt". In Python I can group the nodes selected by the above expression using itertools.groupby, but if there is a way to acheive this purely in XPath, I would prefer it.
An extension to this question: my selector selects all rows, whether the flight is sold out or not. I can select the first flight of every bookable journey using this selector:
//*[contains(#class, "datarow")][.//input]
But if the leg has more than one flight, then I will have to look for following sibling with the same class using another XPath query.
Is there a single XPath query that will return me each bookable leg as a nodeset?
Note: I'm using the Python lxml library, in case that matters.
I can select each row that represents a flight using this XPath selector:
//*[#class="servicecode "]/ancestor::tr[1]
But each flight row is not an independent journey; the flights are really grouped into legs, and these are what I want to select.
The row class alternates for each new leg: the rows of the first leg have class "datarow",
Use:
//tr[#class='datarow'][.//*[#class='servicecode']]
An extension to this question: my
selector selects all rows, whether the
flight is sold out or not. I can
select the first flight of every
bookable journey using this selector:
//*[contains(#class, "datarow")][.//input]
But if the leg has more than one
flight, then I will have to look for
following sibling with the same class
using another XPath query.
Is there a single XPath query that
will return me each bookable leg as a
nodeset?
Yes:
(//tr[#class='datarow'])[1]//input
|
(//tr[#class='datarow'])[1]
//following-sibling::tr[#class='datarow altrow']
[count(preceding-sibling::tr[#class='datarow'])=1]
//input
This XPath expression selects all tr elements that represent each bookable leg (in this case 3 legs) of the first journey.
To get all legs of the second journey, substitute 1 in the above expression with 2.
To get all legs of the k-th journey, substitute 1 in the above expression with the actual value of k.
This does what I want. But is there a more elegant solution?
//*[contains(#class, "columns")]//tr[contains(#class, "datarow")][1]
|
//*[contains(#class, "columns")]//tr[not(contains(#class, "altrow"))]
[preceding-sibling::tr[1]
[contains(#class, "altrow")]]
|
//*[contains(#class, "columns")]//tr[contains(#class,"altrow")]
[preceding-sibling::tr[1]
[not(contains(#class, "altrow"))]]
The second part selects each set of consecutive rows with class not containing "altrow" as a single nodeset.
The third part selects each set of consecutive rows with class containing "altrow" as a single node set.
The first part selects the first set of consecutive rows with class not containing "altrow", because it is not selected by the second part.

Resources