Selecting Node for every time another node is repeated with XQuery with IMPORTXML on Google Sheets - xpath

So here's what I want to do. The following is the xml info (simplified) I get from an invoicing program. I would like to select the Invoicer Name for every time I have a different product. So in
my query I'd get:
Element='<invoicerName>Jack</invoicerName>'
Element='<invoicerName>Jack</invoicerName>'
Element='<invoicerName>Jack</invoicerName>'
Thank you!
<?xml version="1.0" encoding="UTF-8"?>
<invoices>
<invoice>
<invoicerInfo>
<invoicerName>Jack</invoicerName>
</invoicerInfo>
<invoiceDetails>
<productDescription>Soda</productDescription>
<productDescription>Popcorn</productDescription>
<productDescription>Tickets</productDescription>
</invoiceDetails>
<invoice>
</invoices>
I've tried a slew of options but I don't get repeated invoicerName values.

Google Sheets IMPORTXML seems to support XPath 2.0 so you should be able to use:
for $invoice in //invoice
return
for $p in distinct-values($invoice//productDescription)
return
$invoice//invoicerName
That'll generate a list of invoicerName nodes, one for each unique productDescription of a given invoice

If Google Sheets has support for group by you can also use
for $i in //invoice
let $name := $i//invoicerName
return
for $p in $i//productDescription
group by $p
return $name
here is the query in action with extended test data
https://xqueryfiddle.liberty-development.net/6qVSgfb

Related

How to convert CodeIgniter urls into user friendly ones?

I've explored lot of questions and articles regarding this but I can't find how to get this done.
I'm doing a website which provides specifications of several products such as phones, tablets, tv etc. Here's what I've:
Controller - Specs (create and display specification of all products)
Method - Display (fetches detailed specs of selected model and shows)
Method - Index (lists names of all models stored in the table. this is where I build anchor links)
Display method takes three arguments (1, 2, 3).
1 - Type of product (Phones, Tablets, TV etc)
2 - Model Slug (iphone-6, galaxy-tab-s3, bravia-kdl-50w800d etc)
3 - Model ID (1, 4, 13 etc)
My URLs right now are like this:
localhost/sitename/specs/display/phones/iphone-6/1
localhost/sitename/specs/display/tablets/galaxy-tab-s3/4
localhost/sitename/specs/display/tv/bravia-kdl-50w800d/13
What I want to achieve is URLs which are like this:
localhost/sitename/iphone-6
localhost/sitename/galaxy-tab-s3
localhost/sitename/bravia-kdl-50w800d
I don't mind restructuring my tables/controllers/methods or anything else if this can be achieved using whatever.
Thanks for reading.
Edit:
Route.php
$route['default_controller'] = 'Specs/index';
$route['404_override'] = 'Errors/show_404';
$route['translate_uri_dashes'] = FALSE;
This is how I'm building the anchor links (view_file->index.php, called from Index method):
<?php
foreach model(in the table)
echo anchor(specs_controller.display_function.product_type.model_slug.model_id, model_name);
end foreach
?>
I can get the desired URLs with following code in route.php. Only problem is I'm not able to make the 'urlController/urlMethod' return a value in the function which can be assigned to $result variable.
$route['(:any)'] = function ($1)
{
$result = 'urlController/urlMethod/'.$1;
return $result;
};
I'm not sure how to do this. Can someone suggest how I should call 'urlController/urlMethod'?
You could achieve it with CodeIgniter URI Routing. Considering
localhost/sitename/galaxy-tab-s3
maps to
localhost/sitename/specs/display/tablets/galaxy-tab-s3/4
And, model id i.e 4, in this case, is static with respect to galaxy tab s3, as you have not mentioned any such Id in the simplified URL.
My understanding is with every URL localhost/sitename/iphone-6, you need three details about the string 'iphone-6'. i.e. type of product, model-slug, model id. One way could be write something like
$route['sitename/(:any)'] = 'routingController/commonRoutingMethod/$1';
Here, create a new routingController and write some logic into commonRoutingMethod() method, which takes the string like iphone-6 and fetches its all three details i.e. product type, model id etc. And then redirects by building the exact URL using
header('Location: http://localhost/sitename/specs/display/$productType/$modelSlug/$modelId/');
NOTE : There could be more forward ways just using regex match in routes.php, given that you create diffrentiated structure of the string, based on product type and model id e.g p_iphone-6_1 or t_galaxy-tab-s3_4.
Please use below routing code, to achieve it.
localhost/sitename/specs/display/phones/iphone-6/1
localhost/sitename/specs/display/tablets/galaxy-tab-s3/4
localhost/sitename/specs/display/tv/bravia-kdl-50w800d/13
localhost/sitename/iphone-6
localhost/sitename/galaxy-tab-s3
localhost/sitename/bravia-kdl-50w800d
$route['(:any)'] = 'specs/display/$1/$1/$1';
Let me know if you need any help.

Sorting by case using Hibernate

We have a typeahead that allows our customers to do a global search of their clients. Based on a 'filterText', we want to retrieve all the clients where any of the following fields contain the filterText: clientName, clientStreet, clientCity... but now there's a requirement and we want to prioritize the results where the clientName contains the filterText. (They should be shown first)
We currently create a customerSpecification, and the Predicate that it's being used is the following one:
return criteriaBuilder.or(
criteriaBuilder.like(customerName, likeFilter),
criteriaBuilder.like(customerStreet, likeFilter),
criteriaBuilder.like(customerCity, likeFilter),
criteriaBuilder.like(customerState, likeFilter),
criteriaBuilder.like(customerZip, likeFilter),
criteriaBuilder.like(customerCountry, likeFilter),
tempPred
);
and then we use it to get the Page with all the results
customerRepository.findAll(customerSpecification, pageable);
How can we introduce this new requirement? Any approaches?
Some pages suggest to use selectCase, doing something like this:
Expression<Object> caseExpression = criteriaBuilder.selectCase()
.when(criteriaBuilder.like(root.get(CustomerEntity_.name), likeFilter), 1)
.otherwise(2);
Order order = criteriaBuilder.desc(caseExpression);
criteriaQuery.orderBy(order);
But I can't find the way to make it works. I also found some talks about PageRequest, which receives a Sort parameter, but I didn't find how it would help, as this object is too simple for what we're looking for.
Thanks

How can I sum one column from the same table, to produce three different aggregates, using Sequel ORM?

My query is this:
DB[:expense_projects___p].where(:project_company_id=>user_company_id).
left_join(:expense_items___i, :expense_project_id=>:project_id).
select_group(:p__project_name, :p__project_id).
select_more{count(:i__item_id)}.
select_more{sum(:i__amount)}.to_a.to_json
which works.
However, payment methods include cash, card and invoice. So I would like to sum each of those for summary purposes to achieve a discrete total for payments by cash, card, and invoice repsectively. I included the following line into the query
select_more{sum(:i__amount).where(:i__mop => 'card')}.
and the error message was
NoMethodError - undefined method `where' for #<Sequel::SQL::Function:0x007fddd88b5ed0>:
so I created the dataset separately with
ds1 = expense_items.where(:mop=>'card', :expense_company_id=>user_company_id).sum(:amount)
and appended it, at the end of the original query, with
select_append{ds1}
which achieved partial success as the returned json is now:
{"project_name":"project 2","project_id":2,"count":4,"sum":"0.40501E3","?column?":"0.2381E2"}
as can be seen there is no name for this element which I need in order to reference it in my getJSON call. I tried to add an identifier by adding ___a
to the ds1 query as below
ds1 = expense_items.where(:mop=>'card', :expense_company_id=>user_company_id).sum(:amount___a)
but that failed.
In summary, is this the right approach and, in any case, how can I provide an identifier when doing a sequel sum query? In other words sum(:a_column).as(a_name)
Many thanks.
Dataset#sum returns the sum, not a modified dataset. You probably want something like:
ds1 = expense_items.where(:mop=>'card', :expense_company_id=>user_company_id).select{sum(:amount)}
select_append{ds1.as(:sum)}
I am not sure for approach ( better ask Jeremy Evans ) but it work.
You just change: .sum(... to .select_more{:amount___a).as(:desired_name)}
ds1 = expense_items.where(:mop=>'card', :expense_company_id=>user_company_id).select_more{:amount___a).as(:desired_name)}
and actually get that desired_name in db response.

Sorting a Google SpreadSheet or Google Doc table by column

I've made a script that takes data from a spreadsheet , creates a Google Doc and presents selected rows in a Table format in the Doc. Now I'd like to be able to sort that table Alphabetically before the table is created. I've tried using a couple of different approaches like this
function onEdit(){
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var editedCell = sh.getActiveRange().getColumnIndex();
if(editedCell == 2) {
var range = sh.getRange("A2:B10");
range.sort({column: 2});
}
}
This kind of sort works but only onEdit(). I'd like to sort before edit or find away to sort the table as the Google Doc is being generated.
Does anyone have any suggestions.
Many thanks in advance.
Use the onOpen() function instead of the onEdit() function.
Note that you will have to open the document, not just refresh the page to get the function to run.

XQuery and BaseX- How to store the output to a combobox?

I am using BaseX as backend to store XML Files. Front end is in Java. I want to populate
certain elements data into a combobox. The output of the XQuery is string. I am facing problem to load this string in a combobox. Below is the XML file-
<Cities>
<City><C>London</C></City>
<City><C>New Delhi</C></City>
<City><C>Mumbai</C></City>
<City><C>Moscow</C></City>
<City><C>Tokyo</C></City>
<City><C>Mumbai</C></City>
<City><C>Tokyo</C></City>
<City><C>Mumbai</C></City>
<City><C>Tokyo</C></City>
<City><C>Mumbai</C></City>
<City><C>New Delhi</C></City>
</Cities>
Using this XML file, I want to populate all the distinct cities in a combobox. This will be done by following XQuery-
for $x in distinct-values(doc("City")/Cities/City/C)
return $x
The output of this is a simple string -
`London New Delhi Mumbai Moscow Tokyo`
There are 5 cities resulting from the query.
How can I populate this in a combobox..?
This might help:
element select {
distinct-values(doc("City")/Cities/City/C) ! element option { . }
}

Resources