concatenation of one value with multiple values from another xquery - xquery

Hej. I am new at XML-query and have some problem finding a way to combine the result of two xquery into one.
Consider the XML:
<programs>
<program id="488">
<editor>Anna</editor>
<channel>132</channel>
<category>5</category>
</program>
<program id="178">
<editor>Olle</editor>
<channel>132</channel>
<category>68</category>
</program>
<program id="179">
<editor>Olle</editor>
<channel>132</channel>
<category>10</category>
</program>
</programs>
I want to extract list of editors along with the categories they have worked on which would be like this:
<li>Anna 5 </li>
<li>Olle 68 10</li>
Here is the xquery code I am using
let $editors :=
for $d in $sr/sr/programs/program
where $d/channel = "132"
return $d/editor
let $cat :=
for $a in $sr/sr/programs/program
where $a/editor = data($editors)
return concat($a/editor ,' ', $a/category)
for $result in distinct-values($cat)
return <li>{string($result)}</li>
Appreciate all the helps!

I would iterate over the distinct list of editors, obtained from an XPath with a predicate to restrict to those with channel equal to 132, and then retrieve a distinct list of categories for those editors with a similar XPath with predicate filter, and then return the HTML with those values:
for $editor in distinct-values($sr/sr/programs/program[channel eq 132]/editor)
let $categories :=
distinct-values($sr/sr/programs/program[channel eq 132 and editor eq $editor]/category)
return <li>{$editor, $categories}</li>

Related

Filemaker Pro - Using Script to populate report layout

I have a problem where I have a list of fields from a table (not static, can be modified by user), and I need to generate a report using these user selected fields. The report can show all the rows, no need for aggregation or filtering.
I thought I could create a report layout then using a filemaker script to populate it but can't seem to find the right commands, can someone let me know how I could achieve this?
I'm using filemaker pro 18 advanced
Thanks in advance!
EDIT: Since you want a dynamic report, then I recommend you look up a technique called "Virtual List" for rendering the data.
Here's an example script that iterates over a found set of records and builds the virtual list data in a variable (it doesn't show how to render it though):
# Field names and delimiter
Set Variable [ $delim ; Value: Char(9) // tab character ]
# Set these dynamically with a script parameter
Set Variable [ $fields ; Value: List ( "Contacts::nameFirst" ; "Contacts::nameCompany" ; "Contacts::nameLast" ) ]
Set Variable [ $fieldCount ; Value: ValueCount ( $fields ) ]
Go to Layout [ “Contacts” (Contacts) ; Animation: None ]
Show All Records
Go to Record/Request/Page [ First ]
# Loop over all the records and append a row in the $data variable for each
Set Variable [ $data ; Value: "" ]
Loop
# Get the delimited field values
Set Variable [ $i ; Value: 0 ]
Set Variable [ $row ; Value: "" ]
Loop
Exit Loop If [ Let ( $i = $i + 1 ; $i > $fieldCount ) ]
Set Variable [ $value ; Value: GetField ( GetValue ( $fields ; $i ) ) ]
Insert Calculated Result [ Target: $row ; If ( $i > 1 ; $delim ) & $value ]
End Loop
enter code here
# Append the new row of data to the list variable
Insert Calculated Result [ Target: $data ; If ( Get ( RecordNumber ) > 1 ; ¶ ) & $row ]
Go to Record/Request/Page [ Next ; Exit after last: On ]
End Loop
# Save to a global variable to show in a virtual list layout
Set Variable [ $$DATA ; Value: $data ]
Exit Script [ Text Result: ]
please note this code is just one of many possible formats the virtual list can take. A lot of people, myself included, prefer to use JSON objects or arrays for each row of the list since it automatically handle field values with carriage returns. This is sort of the old-fashioned way. Kevin Frank at FileMaker Hacks has some good recent articles about virtual list techniques if you're interested.
PS, another great technique for rendering table data dynamically is to collect the data in a JSON array and render it in a webviewer with https://datatables.net/
I did something like this for the oncology department of UM om 1980 or so using 4th Dimension and a new plug in that used one line of code to create a web browser with all the functions that a doctor might want. The data was placed inside a variable as it was sent/returned and 4D could use a variable in the report to display the data.
FileMaker does not have this ability built in as 4D did so you will have to do it yourself.JSON is the most likely tool that I am familiar with. YouTube has many videos on JSON.
You have two classes of variables for your report: Column headers and column data to display. Fortunately Filemaker is quite good and very easy to design. Just make a typical report and replace the text/header or field names with a JSON variable or any. $ColumnName = JSON variable.
Create a JSON calculated field in the database. In that calculated field set the JSON variable and this can be used for all of the columns.
This is the essence of the idea with the final result to be determined by you. What you are asking for is not easy and would require serious work by a skilled JSON scripter.

How to match space in MarkLogic using CTS functions?

I need to search those elements who have space " " in their attributes.
For example:
<unit href="http:xxxx/unit/2 ">
Suppose above code have space in the last for href attribute.
I have done this using FLOWER query. But I need this to be done using CTS functions. Please suggest.
For FLOWER query I have tried this:
let $x := (
for $d in doc()
order by $d//id
return
for $attribute in data($d//#href)
return
if (fn:contains($attribute," ")) then
<td>{(concat( "id = " , $d//id) ,", data =", $attribute)}</td>
else ()
)
return <tr>{$x}</tr>
This is working fine.
For CTS I have tried
let $query :=
cts:element-attribute-value-query(xs:QName("methodology"),
xs:QName("href"),
xs:string(" "),
"wildcarded")
let $search := cts:search(doc(), $query)
return fn:count($search)
Your query is looking for " " to be the entirety of the value of the attribute. If you want to look for attributes that contain a space, then you need to use wildcards. However, since there is no indexing of whitespace except for exact value queries (which are by definition not wildcarded), you are not going to get a lot of index support for that query, so you'll need to run this as a filtered search (which you have in your code above) with a lot of false positives.
You may be better off creating a string range index on the attribute and doing value-match on that.

Joining sequence and document in XQUERY

I want to join document and sequence in XQUERY.
I'am trying this code:
let $in_xml :=
<ss>
<s>
<p>2016/2/18/11/protocol13818.xml</p>
<n>service1_1</n>
<d>2016-04-01</d>
</s>
<s>
<p>2016/2/18/15/protocol13819.xml</p>
<n>service_2</n>
<d>2016-04-02</d>
</s>
</ss>
for $a in /version,
$i in $in_xml
where $a/fn:base-uri() = $i/s/p
return <a>{$a//id/value/text()," ", $i//n}</a>
And having this result:
<a>c2e9bb01-acc1-4a64-b39b-f30ef514c5ec <n>service1_1</n>
<n>service_2</n>
</a>
<a>50543b71-48b8-41f6-956e-b444c5ad0abe <n>service1_1</n>
<n>service_2</n>
</a>
Why sequence is not filtered?
I want, that result will be look like this:
<a>c2e9bb01-acc1-4a64-b39b-f30ef514c5ec <n>service1_1</n>
</a>
<a>50543b71-48b8-41f6-956e-b444c5ad0abe <n>service1_2</n>
</a>
How can i do this? Any ideas? Thanks!
When you do $i in $in_xml, you iterate over every element in $in_xml, which is just $in_xml itself, since it is an element and not a sequence. To iterate over all the children of $in_xml, you need to select them:
You want something like
for $a in /version,
$i in $in_xml/s
where $a/fn:base-uri() = $i/p
return <a>{$a//id/value/text()," ", $i/n}</a>

array count doesn't show correct number, rather just "1"

I have several John Jones with different names in a form. I submit the form to another program which uses "$checkednames = implode(', ', $_POST['raters']);". I echo $checkednames and see all the names but "count($checkednames)" is 1 and not the number of names. What could be wrong?
I appreciate any help.
You may seen the results by going to:
www.golfcourseratingassistant.org/ratecourse/
select Course name > Select Tee Box > Course Data ...select for all lists then "Save Data".
Selected data is only valid for the current session.
It will be 1 only, implode() returns a string containing a string representation of all the array elements in the same order, with the glue string between each element. See Manual
explode() will return an array of strings
So count() after explode() will give you the number of elements.
You can see the names because it is one string.
$array = array('lastname', 'email', 'phone');
$comma_separated = implode(",", $array);
echo count($comma_separated);// Output will be 1
For explode():
$string= "lastname,email,phone";
$array= explode(",", $string);
echo count($array); //output will be 3

Return multiple data elements

Using Xquery, how can I search the file below (consisting of many items), for all items with 'XC' in the part-number (there are many), then for matches return all 3 of the interesting data elements (part-number, part-name, and name)? The return is the main problem--my attempts result in every permutation of the interesting data elements. Thank you!
<catalog>
<item>
<description>
<partref>
<part-id>
<part-number>XC51222</part-number>
</part-id>
</partref>
<part-name>DSP, Network Vectoring<part-name>
<vendors>
<vendor1>
<pay-to>
<name>JCOF Industries</name>
</pay-to>
</vendor1>
</vendors>
</description>
&lt/item>
&ltitem>
&lt/item>
[many items…]
</catalog>
xquery version "1.0";
let $sep := ','
for $x in catalog/item
where fn:matches($x/description/partref/part-id/part-number, 'XC')
return fn:string-join( ($x/description/partref/part-id/part-number/text(), $x/description/part-name/text(), $x/description/vendors/vendor1/pay-to/name/text()), $sep)

Resources