Tim,
You should be able to use the indexes if you can enumerate the parent
element names. Let's start with some test docs....
(: build test case :)
let $names :=
for $i in 1 to 8
return codepoints-to-string(string-to-codepoints("a") - 1 + $i)
for $i in 1 to 100
let $name-index := 1 + $i count($names)
let $id := concat("t", string($i))
let $uri := concat("test/", string($i))
return
xdmp:document-insert(
$uri,
element { $names[$name-index] } {
attribute xml:id { $id },
xdmp:integer-to-hex(xdmp:random())
})
This inserts 100 docs that look like:
...
<a xml:id="t16">39c5218f30d8434f</a>
<b xml:id="t17">74fb0615f8a17110</b>
<c xml:id="t10">53439ea8dd47f4d0</c>
<d xml:id="t11">828dd36894cfa367</d>
<e xml:id="t12">87d537f4eb96e1b0</e>
<f xml:id="t13">154eea3e15b59fcf</f>
<g xml:id="t14">701dfd435977a3fc</g>
<h xml:id="t15">39842113ea1e916e</h>
...
I can query these documents efficiently using XPath:
/(a|b|c|d|e|f|g|h)[...@xml:id eq "t1"]
=>
<b xml:id="t1">60271146593168d7</b>
According to xdmp:query-trace(), this selects 1 fragment to filter. We
can also write this query in a few other ways. For example, I might want
to store a list of all the possible QNames in a variable, so that I can
compose the query more dynamically:
let $names :=
for $i in 1 to 8
return xs:QName(codepoints-to-string(string-to-codepoints('a') - 1 + $i))
return /*[node-name(.) = $name...@xml:id eq "t1"]
We can use a similar technique with a cts:query:
let $q :=
cts:element-attribute-value-query(
for $i in 1 to 8
return
xs:QName(
codepoints-to-string(
string-to-codepoints("a") - 1 + $i)),
xs:QName("xml:id"),
"t1")
return cts:search(doc(), $q)
All three of these forms are efficient.
thanks,
-- Mike
On 2009-07-20 19:02, Tim Finney wrote:
Dear All,
I would like to be able to find the element associated with an @xml:id
quickly, without knowing the element path or name. Can this be done with
MarkLogic?
The id() function is meant to do this but it is horribly slow when faced
with masses of documents. For example,
collection()//*...@xml:id eq 'something']
takes thirty seconds and I need it to work in hundredths of seconds
instead.
(If I put in the element name, the above query runs in about a hundredth
of a second.)
Best,
Tim Finney
University of Virginia Press
_______________________________________________
General mailing list
[email protected]
http://xqzone.com/mailman/listinfo/general
_______________________________________________
General mailing list
[email protected]
http://xqzone.com/mailman/listinfo/general