XSLT/ Xpath how to accumulate / get total of a node based on a condition in another node - xpath

I need to get two totals CreditCardTotal and CashTotal and have to display them in another tag AccountCost, as shown below.
Basically, I need get the expense amount and check to see if it is a credit card or cash and then add it to the respective total variable. Or if there is a more elegant way please let me know.
I am completely stumped and new to Xpath. Thanks, and will truly appreciate your time and effort.
<ExpenseCatDetail>
<Expense>500</Expense>
<PaymentMethod>CreditCard</PaymentMethod>
<AccountCost>700</AccountCost>
</ExpenseCatDetail>
<ExpenseCatDetail>
<Expense>100</Expense>
<PaymentMethod>Cash</PaymentMethod>
<AccountCost>400</AccountCost>
</ExpenseCatDetail>
<ExpenseCatDetail>
<Expense>200</Expense>
<PaymentMethod>CreditCard</PaymentMethod>
<AccountCost>700</AccountCost>
</ExpenseCatDetail>
<ExpenseCatDetail>
<Expense>300</Expense>
<PaymentMethod>Cash</PaymentMethod>
<AccountCost>400</AccountCost>
</ExpenseCatDetail>

Element construction is not possible with XPath, you would require XQuery for that.
To fetch a single sum, use
sum(//ExpenseCatDetail[PaymentMethod="Cash"]/AccountCost)
and replace "Cash" as needed.
Using XPath 2.0, you could at least calculate both sums in one statement and return a sequence of both values (is usually mapped to an array or similar construct in other programming languages):
(
sum(//ExpenseCatDetail[PaymentMethod="Cash"]/AccountCost),
sum(//ExpenseCatDetail[PaymentMethod="CreditCard"]/AccountCost)
)

Related

Extract substring using importxml and substring-after

Using Google sheet 'ImportXML', I was able to extract the following data from a url(in cell A2) using:
=IMPORTXML(A2,"//a/#href[substring-after(., 'AGX:')]").
Data:
/vector/AGX:5WH
/vector/AGX:Z74
/vector/AGX:C52
/vector/AGX:A27
/vector/AGX:C6L
But, I want to extract the code after "/vector/AGX:". The code is not fixed to 3 letters and number of rows is not fixed as well.
I used =INDEX(SPLIT(AP2,"/,'vector',':'"),1,2). But it applied to only one line of data. Had to copy the index+split function to the whole column and had to insert an additional column to store the codes.
5WH
Z74
C52
A27
C6L
But, I want to be able to extract the code(s) after AGX: using ImportXML in one go. Is there a way?
Solution
Your issue is in how you are implementing the index formula. The first parameter returns the rows (in your case each element) and the second the column (in your case either AGX or the code after that).
If instead of getting a single cell we apply this formula on a range and we do not set any value for the row, the formula will return all the values achieving what you were aiming for. Here is its implementation (where F1:F5 will be the range of values you want this formula to be applied) :
=INDEX(SPLIT(F1:F5,"/,'vector',':'"),,2)
If you are interested in a solution simply using IMPORTXML and XPATH, according to the documentation you could use a substring as follows:
=IMPORTXML(A1,"//a/#href[substring-after(.,'SGX:')]")
The drawback of this is that it will return the full string and not exclusively what is after the SGX: which means that you would need to use a Google sheet formula to splitting this. This is the furthest I have achieved exclusively using XPath. In XML it would be easier to apply a forEach and really select what is after the : but I believe in sheets is more complicated if not impossible just using XPath.
I hope this has helped you. Let me know if you need anything else or if you did not understood something. :)

Google Sheets/Excel: Checking if a time falls within a range

I'm trying to find a way to see if I can find a way to determine if a time that I stipulate falls between two other times. For example:
Start End
11:33:48 11:53:48
12:20:22 12:38:21
12:39:27 13:00:09
14:16:23 14:20:49
14:20:54 14:22:56
Then, I want to check if a cell (here the value of 12:50 in cell E30) falls between ANY two values in a range in THE SAME ROW. For me, I can get the obvious way to check for this in one row, and this simple version totally works:
=If(AND(E30>A4,E30<B4), "TRUE", "FALSE")
However, I want to check if that number falls within ANY of the values within the ROWS above cells in a range, and I can't get that to work. For example, I tried this and it didn't work:
=If(AND(E30>A:A,E30<B:B), "TRUE", "FALSE")
I also tried a simple countif variation but that didn't do it either:
=COUNTIFS(A:A,">"&E30,B:B,"<"&E30)
Any advice on how to adjust one of these formulas to get it to work?
Try switching the angle brackets around:
=COUNTIFS(A:A,"<"&E30,B:B,">"&E30)
I think this should work for the above data set -
=IF((FILTER(A2:B6, D2>A2:A6,D2<B2:B6)),TRUE,FALSE)
This will give you if there is any match or not.
For the number of rows count that match -
=ROWS((FILTER(A2:B6, D2>A2:A6,D2<B2:B6)))
Alomsot =IF(Q2>R2,IF(AND($X$16>HOUR(Q2),$X$16<(HOUR(R2)+12)),1,0),IF(AND(HOUR($X$14)>=HOUR(Q2),HOUR($X$14)<=HOUR(R2)),1,0))

Return the count of courses using satisfies contains XQuery

I have been struggling to return the count of courses from this XML file that contain "Cross-listed" as their description. The problem I encounter is because I am using for, it iterates and gives me "1 1" instead of "2". When I try using let instead I get 13 which means it counts all without condition even when I point return count($c["Cross-listed"]. What am I doing wrong and how can I fix it? Thanks in advance
for $c in doc("courses.xml")//Department/Course
where some $desc in $c/Description
satisfies contains($desc, "Cross-listed")
return count($c)
The problem I encounter is because I am using for
You are quite correct. You don't need to process items individually in order to count them.
You've made things much too difficult. You want
count(doc("courses.xml")//Department/Course[Description[contains(., "Cross-listed"]])
The key thing here is: you want a count, so call the count() function, and give it an argument which selects the set of things you want to include in the count.

Report Builder Expressions

Im new to Report Builder and having issues with some expressions that Im trying to implement in a report. I got the standard ones to work however as soon as I try any distinctions, I get error messages. Over the last couple weeks, Ive tried many combinations, read the expression help, google and looking at other questions at internet sites. To reduce my frustrations, I even would jump to other expressions and walk away hoping I would have different insight coming back.
Its probably something simple or something I dont know about writing expressions.
Im hoping that someone can help with these expressions; they are the versions I get the least errors with(usually just expression expected) and show what Im trying to accomplish.
=IIF((Fields!RECORDFLAG.Value)='D',COUNTDISTINCT(Fields!TICKETNUM.Value),0)
=IIF((Fields!TRANSTYPE.Value)='1' and (Fields!RECORDFLAG.VALUE)='A' or
'B',SUM(Fields!DOLLARS.Value),0)
=IIF((Fields!TRANSTYPE.Value)='1' and
(Fields!RECORDFLAG.VALUE)='P',SUM(Fields!DOLLARS.Value),0)
=Sum([DOLLARS] case when [RECORDFLAG]='P' then -1*[DOLLARS])
Thank You.
=IIF((Fields!RECORDFLAG.Value)=”D”,COUNTDISTINCT(Fields!TICK‌​ETNUM.Value))
The error message gives you the answer here - no false part of the iif() has been specified. Use =IIF((Fields!RECORDFLAG.Value)=”D”,COUNTDISTINCT(Fields!TICK‌​ETNUM.Value), 0)
=IIF((Fields!TRANSTYPE.Value)="1" and (Fields!RECORDFLAG.VALUE)="A" or "B",SUM(Fields!DOLLARS.Value),0)
This is not how an OR works in SSRS. Use:
=IIF((Fields!TRANSTYPE.Value)="1" and (Fields!RECORDFLAG.VALUE="A" or Fields!RECORDFLAG.Value = "B"),SUM(Fields!DOLLARS.Value),0)
The 0s are returned due to your report design. countdistinct() is an aggregate function - it's meant to be used on a set of data. However, your iif() is only testing on a per row basis - you're basically saying "if the current row is thing, count all the distinct values" which doesn't make sense. There are a couple of ways forward:
You can count the number of times a certain value occurs in a given condition using a sum(). This is not the same as the countdistinct(), but if you use =sum(iif(Fields!RECORDFLAG.Value = "D", 1, 0)) then you will get the number of times RECORDFLAG is D in that set. Note: this requires the data to be aggregated (so in SSRS, grouped in a tablix).
You can use custom code to count distinct values in a set. See https://itsalocke.com/aggregate-on-a-lookup-in-ssrs/. You can apply this even if you have only one dataset - just reference the same one twice.
You can change the way your report works. You can group on Fields!RECORDFLAG.Value and filter the group to where Fields!RECORDFLAG.Value = "D". Then in your textbox, use =countdistinct(Fields!TICKETNUM.Value) to get the distinct values for TICKETNUM when RECORDFLAG is D.

Yahoo Pipes: Extracting number from feed item for use in URL builder

Been looking all over the place for a solution to this issue. I have a Yahoo Pipe (http://pipes.yahoo.com/pipes/pipe.info?_id=e5420863cfa494ee40e4c9be43f0e812) that I've created to pull back image content from the Bing Search API. The URL builder includes a $skip attribute that takes an integer and uses it to select the starting (index) point for the result set that the query returns.
My initial plan had been to use the math engine in the Wolfram Alpha API to generate a random number (randomInteger[1000]) that I could use to seed the $skip value each time that the pipe is run. I have an earlier version of the pipe where I was able to get the query / result steps working using either "XPath Fetch" and "Fetch Data". However, regardless of how I Fetch the result, the response returns as an attribute / value pair in a list item.Even when I use "Emit items as string" in XPath Fetch, I still get a list with a single item, when what I really want is the integer that I can plug into my $skip attribute.
I've tried everything in Pipes I can think of, and spent a lot of time online looking for an answer. Is there anyway to extract text (in this case, a number) from a single list item and then use the output as input to "wire" a text parameter in another Pipes block? Any suggestions / ideas welcome. In the meantime, I'm generating a sorta-random number by manipulating a timecode hash, but it just feels tacky :-)
Thanks!
All the sources are for repeated items. You can't have a source that just makes a single number.
I'm not really clear what you're trying to do. You want to put a random number into part of the URL string that gets an RSS feed?

Resources