XQuery: Select a node in the context of a varaible - xpath

In order to learn XQuery I tried to run the following XQuery command in BaseX
let $x := doc("test.xq")//h2/following-sibling return $x::h2
I supposed it should be equivalent to
let $x := doc("test.xq")//h2/following-sibling::h2 return $x
But it gives the following error and doesn't work while the second command works
Error:
Stopped at D:/Program Files/BaseX/data/test.xq, 1/66:
[XPST0003] Unexpected end of query: '::h2'.
In general, how can I select some nodes (h2) in the context provided by a variable ($x := doc("test.xq")//h2/following-sibling)

That's not how variables work I'm afraid. It looks like you're trying to treat the variable declaration as a kind of "macro" and expecting its textual definition to be substituted in when the variable is referenced, but in fact XQuery variables are more like local variables in C or Java - the definition expression is evaluated to give a value or sequence and when you refer to the variable you get that value back.
So both the definition and referencing expressions need to be valid expressions in their own right. If you wanted to store the list of all following sibling elements in the variable and then later filter for just the h2 elements you'd need something like
let $x := doc("test.xq")//h2/following-sibling::* return $x[self::h2]

You can't separate the expression at that part, see following-sibling::h2 as one unit. You can do the following instead :
let $x := doc("test.xq")//h2 return $x/following-sibling::h2

Related

XQuery concat to the same variable

Simple code there-
let $sV2 :=''
for $i in (1 to 2)
let $sV1 := 'test1'
let $sV2 := if (fn:string-length($sV2) != 0) then fn:concat($sV2,'||',$sV1) else ($sV1)
return
<test>{$sV2}</test>
i get the same output
<test>test1</test>
<test>test1</test>
whereas i expect
<test>test1</test>
<test>test1||test1</test>
what am i doing wrong? i tried to debug but why does V2 initialize to null/'' for second iteration.
Note- I have to use xquery 1.0 do to some product limitations.
How do i get the expected output?
XQuery is a functional language. As such, it does not allow you to change the value of a variable once it has been assigned.
There are many other ways to reach the same results, though. Your specific query can e.g. be rewritten as follows:
for $i in 1 to 2
return <test>{
string-join(for $n in 1 to $i return 'test1', '||')
}</test>

How evaluate concatenated string as indexed XPath expression in VB6

I've built an Xpath expression by concatenating strings in VB6:
strXPath = "xDOC.selectNodes(" & """/GroupType1""" & ").item(" & CStr(i) & ").selectNodes(" & """/OperationStageCollection/OperationStage""" & ").length"
"i" is an integer used to index into
I want to evaluate strXPath to get a loop counter, for example:
n = CInt(strXPath)
n is declared as Integer; strXPath is declared as string. VB6 throws a Type Mismatch error on the above evaluation expression. I must be missing something obvious. How can I evaluate strXPath?
I realize that there may be errors in the XPath expression itself, but I'd like to get the evaluation working in order to debug such possible errors.
Try removing some of the double-quotes:
iLength = xDOC.selectNodes("/GroupType1").item(i).selectNodes("/OperationStageCollection/OperationStage").length
This should return the length property you want, as an Integer.
Then you can use iLength in your loop.
#BRW: both of your questions are very specific, i.e. how to achieve certain results using XPath. But I have the suspicion that if you would explain what (data) you try to retrieve form the XML, commenters might show you ways you didn't think of, e.g. say you want to iterate through all <OperationEvent>s within a <OperationEventCollection>, a single <OperationEvent> can be retrieved by //GroupType1/OperationStageCollection/OperationStage/OperationEventCollection/OperationEvent[1-based-index], e.g. //GroupType1/OperationStageCollection/OperationStage/OperationEventCollection/OperationEvent[1], which results in a single XML node:
<OperationEvent>
<OperationEventDate1>2018-12-16</OperationEventDate1>
<OperationEventCode>5</OperationEventCode>
<OperationEventDate2>2018-05-16</OperationEventDate2>
</OperationEvent>
So instead multiple selectNodes methods, one proper XPath query might yield the desired outcome right away.

Go- Why Does My For Loop Throw "Unexpected Semi-colon or New-line"?

I'm writing a dice rolling function. In order to add the result of each die, I added to an output variable using a for loop. However, I'm getting an error thrown when I attempt to build;
syntax error: unexpected semicolon or newline, expecting {
This was thrown on the line initializing the for loop.
Here is my code:
for i := 0; i < [0]si; i++ {
output := output + mt.Intn([1]si)
}
si is simply an int array holding 2 values, and mt is the name I gave to math/rand when I imported it.
Your loop has several problems:
The use of square brackets is odd. Outside of type definitions, these go after slice/array names, e.g. x[i] would give you the ith element of the slice x.
There is no reference to i inside the loop body, and thus each iteration of the loop will do the same thing.
You should probably write output = output + ... without the colon. Otherwise, a new variable output is declared during each iteration of the loop, and forgotten immediately after so that the loop has no effect.
The compiler error is probably caused by the first of these problems.
You access an array with varname[idx] in Go, just like in most other languages. It's only when declaring a new array of type si that you use the [size]si prefix syntax. You're getting the error because your code is syntactically invalid. You're trying to compare i to an array of 0 si s.

how to use index inside range in html/template to iterate through parallel arrays?

I'm executing a template with 2 parallel arrays (same size) and I want to list items from both arrays in parallel, how do I use index inside of range?
this obviously doesn't work:
{{range $i, $e := .First}}$e - {{index .Second $i}}{{end}}
One of the predefined global template functions is index.
index Returns the result of indexing its first argument by the
following arguments. Thus index x 1 2 3 is, in Go syntax,
x[1][2][3]. Each indexed item must be a map, slice, or array.
So you are on the right track. The only issue is that you are not accounting for the fact the dot has been reassigned within the range block.
So you need to get back to the original dot, for that we have the following
When execution begins, $ is set to the data argument passed to Execute, that is, to the starting value of dot.
So (assuming there is nothing else going on in your template) you should be able to do:
{{range $i, $e := .First}}$e - {{index $.Second $i}}{{end}}
Personally though, I would create a template function called zip that accepts multiple slices and returns a slice of each pair of values. It would look cleaner in your template and probably get reused somewhere.

Issue w/ Symbol Substitution in Mathematica

I want to define a symbol and use it within a function. For example, with IDnumbers defined as a list of numbers:
ParallelMap[{#1, Name[#1], Age[#1]} &, IDnumbers]
With userlist={#1, Name[#1], Age[#1]} becomes:
ParallelMap[userlist &, IDnumbers]
It works just fine with the list itself in the code, but not with the symbol. The same thing happens with a list of strings vs. a symbol assigned to a list of strings. Why is this?
Since f[#]& is shorthand for Function[f[#]] you should always complete your anonymous function with a trailing & to get a working function.
In your example:
userlist={#1, Name[#1], Age[#1]}&
ParallelMap[userlist, IDnumbers]
More thorough explanation:
By just using something like f[#] you get (in FullForm[])
In[15] := f[#] // FullForm
Out[15]//FullForm = f[Slot[1]]
whereas this gets transformed to a Function by the trailing & operator:
In[16] := f[#]& // FullForm
Out[16]//FullForm = Function[f[Slot[1]]]
If you do this in two steps, & doesn't evaluate the intermediate variable expr:
In[25]:= expr = f[#]//FullForm
In[26]:= expr &
Out[25]//FullForm = f[Slot[1]]
Out[26] = expr &
You can force the evaluation of expr before it gets wrapped in the Function[] by using Evaluate[]:
In[27]:= expr=f[#]//FullForm
In[28]:= Evaluate[expr]&
Out[27]//FullForm = f[Slot[1]]
Out[28] = f[Slot[1]]&
Another way is to supply the Function[] wrapper yourself:
userlist={#1, Name[#1], Age[#1]}
ParallelMap[Function[userlist], IDnumbers]
Personally, i would consider this bad coding style. Just get used to always finishing an anonymous function with a trailing & like you would supply a closing paranthesis ) to a corresponding opening one (.
Edit
Ok, in your case of a dynamically generated anonymous function i can see why you couldn't supply the & directly. Just wrap the expression with the Slot[]s in a Function[] instead.

Resources