string in xpath - xpath

I have a string and I want to use it as a selector in xpath to select a node with name as value of the string.
declare variable $get_count := <count><comedy>1</comedy></count>;
(: $string = "comedy" :)
let $value = $get_count/$string (: but this doesn't return anything)
How shall i do it?

let $value = $get_count/$string (: but this doesn't return anything)
Use:
declare variable $get_count := <count><comedy>1</comedy></count>;
declare variable $string := "comedy";
let $value := $get_count/*[name()=$string]
return
$value
When this is applied on any XML document (not used), the wanted, correct result is produced:
<comedy>1</comedy>

Related

How to insert character at element to string in golang [duplicate]

Most programming languages have a function that allows us to insert one string into another string. For example, I can take the string Green and the string HI, and perform an operation Green.insert(HI,2) to get the resulatant string GrHIeen. But such a function does not come with the standard GO lang library.
Is there any Golang function which I can use to insert a string inside an string?
For example
string = "</table></body></html>"
// I want Following Output
string = "</table><pagebreak /></body></html>"
You can simply use slice operations on the string:
package main
func main() {
p := "green"
index := 2
q := p[:index] + "HI" + p[index:]
fmt.Println(p, q)
}
Working example: https://play.golang.org/p/01phuBKuBB
You could turn the first string into a template for Sprintf. It would look like this:
p := "</table>%s</body></html>"
out := fmt.Sprintf(p,"<pagebreak />")
Working code here: https://play.golang.org/p/AInfyQwpy2
I had used rune and bytes.Buffer to insert <\b> bold tags at between two indexes and build a result string as below.
for j:=0; j< len(resultstrIntervals);j++{
startIndex:= resultstrIntervals[j].Start
endIndex:= resultstrIntervals[j].End
for i <= endIndex && i <= len(s) {
if i == startIndex{
buffer.WriteRune('<')
buffer.WriteRune('b')
buffer.WriteRune('>')
}else if i == endIndex{
buffer.WriteRune('<')
buffer.WriteRune('/')
buffer.WriteRune('b')
buffer.WriteRune('>')
}
if i < len(strArr){
buffer.WriteRune(strArr[i])
}
i++
}
}
fmt.Print(buffer.String())
example

XQuery: How to convert string into XPath rules

The following is a simple XQuery that would run an xpath against an htm file and return how many matching tags were found. The xpath rules are in variable $rule, but I would like to use the string variable $rule-unused instead. How can I convert this string into a node-set and have it run against my document similar to the $document//$rule ?
xquery version "3.1";
declare namespace persons="http://www.test.com/test/profiles";
declare variable $uri as xs:string := "/db/apps/Persons/profile.htm";
declare variable $rule-unused as xs:string := "//persons:relationship";
let $document := doc($uri)
let $rule := //persons:relationship
let $all-lines := $document//$rule
return
<test>
{
count( $all-lines )
}
</test>

Xquery get the children nodes by passing parent value at run time

I need to pass a value at run time get all the childen elements.
For example this is my XML:
<person>
<details1>
<name>jack</name>
<age>26</age>
</details1>
<details2>
<name>john</name>
<age>48</age>
</details2>
</person>
And my query:
let $y as xs:string := "details1"
let $x := fn:doc(cts:uri-match('*person.xml'))
return $x/$y
So here I am expecting the result as
<details1>
<name>jack</name>
<age>26</age>
</details1>
but it returns the same name as that of $y i.e. "details1"
or if I query this way
let $y as xs:string := "details1"
let $x := fn:doc(cts:uri-match('*person.xml'))
return $x//$y
the result would be "details1" for 12 times
I am new to XQuery please help me in solving the issue
It seems like you attempt to use a string $y as a node step. However, in XPath/XQuery a path step is different from a string, so you can't simple add a string as path step. Instead, you could look for all descendent elements with the requirement that they do have the same name, i.e.:
let $y as xs:string := "details1"
let $x := fn:doc(cts:uri-match('*person.xml'))
return $x/*[name(.) = $y]
As drkk said, you have to look at the name of the element. But using name() is dangerous. It returns the lexical name of the element, which might be ns:elem if the element has a prefix. And the prefix can be different in every document, even for the same namespace. So either you match only by local name:
let $y as xs:string := 'details1'
let $x := fn:doc(cts:uri-match('*person.xml'))
return
$x/*[local-name(.) eq $y]
Or better, match a QName (note the node-name() usage):
let $y as xs:string := xs:QName('details1')
let $x := fn:doc(cts:uri-match('*person.xml'))
return
$x/*[node-name(.) eq $y]
and if the element name is within a namespace (note the difference between xs:QName() and fn:QName()):
let $y as xs:string := fn:QName('namespace-uri', 'details1')
let $x := fn:doc(cts:uri-match('*person.xml'))
return
$x/*[node-name(.) eq $y]
One alternative is to use xdmp:value() to evaluate the XPath dynamically:
let $y as xs:string := "details1"
let $x := fn:doc(cts:uri-match('*person.xml'))
return xdmp:value("$x/" || $y)
If $x is a large data set, that approach can have performance benefits by removing the need to get the element name for every document in the set.
For more detail, see:
http://docs.marklogic.com/xdmp:value?q=xdmp:value&v=8.0&api=true
Hoping that helps,

Specman e: When colon equal sign ":=" should be used?

I saw in some Specman e code example the use of := (colon-equal sign), e.g.:
var regs_type := rf_manager.get_exact_subtype_of_instance(graphics_regs);
When and why should we use := ?
Thank you for your help.
The := means declare a variable of the type the expression on the right returns and assign it to that value. Basically, in your example, the function get_exact_subtype_of_instance(...) returns a value of type rf_struct. The regs_type variable will be declared to that type.
This code is equivalent to (but shorter than):
var regs_type : rf_struct = rf_manager.get_exact_subtype_of_instance(graphics_regs);
This syntax is particularly helpful when casting:
var foo := some_struct.as_a(FOO some_struct_type);

Xquery returning list of maps rather than map

I have the following function
declare private function local:get-map() as map:map*
{
let $map := map:map()
for $chart in xdmp:directory("/charts/")
for $panel in $chart/delphi:chart/delphi:panels/delphi:panel
for $dataline in $panel/delphi:datalines/delphi:dataline
let $datasetHref := $dataline/delphi:link[#rel="dataset"]/#href
let $axisId := $dataline/delphi:dimensions/delphi:dimension[#field="y"]/#axis
let $label := $panel/delphi:axes[#dimension="y"]/delphi:axis[#id=$axisId]/#label
let $l := map:get ($map, $datasetHref)
let $updateMap := if (fn:exists ($l)) then () else map:put ($map, $datasetHref, $label)
return $map
};
I have been forced to declare the return type as map:map* because for some reason $map is an array of maps rather than a map. The array contains many items, where each item contains the same map that I need. So when I call this method I use take the first item. Problem is this is not exactly elegant. What I don't understand is why do I get multiple copies of the same map in an array. I expected the code to return a single map. How do I rewrite this to solve the issue?
It's returning a sequence of maps, because each iteration of each of the "for"s returns it. Try this:
declare private function local:get-map() as map:map
{
let $map := map:map()
let $populate :=
for $chart in xdmp:directory("/charts/")
for $panel in $chart/delphi:chart/delphi:panels/delphi:panel
for $dataline in $panel/delphi:datalines/delphi:dataline
let $datasetHref := $dataline/delphi:link[#rel="dataset"]/#href
let $axisId := $dataline/delphi:dimensions/delphi:dimension[#field="y"]/#axis
let $label := $panel/delphi:axes[#dimension="y"]/delphi:axis[#id=$axisId]/#label
let $l := map:get ($map, $datasetHref)
return if (fn:exists ($l)) then () else map:put ($map, $datasetHref, $label)
return $map
};
This does the FLWOR statement in its own let, then returns the map.

Resources