如何不使用ancestor-or-self::*构建祖先树?XQuery环境不支持该轴求助
ancestor-or-self::* Axis Not Supported in XQuery Got it, let's figure out how to grab those ancestor-and-self nodes when your XQuery environment doesn't support the ancestor-or-self::* axis. Here are a couple of reliable workarounds you can try:
1. Recursive Function (Most Flexible)
Write a simple recursive function that builds the node list by starting with the current node and traversing up through each parent until there are no more parents left. This mimics exactly what ancestor-or-self::* does.
declare function local:get-ancestors-or-self($node as node()) as node()* { -- Start with the current node $node, -- If there's a parent node, recurse to add it and its ancestors if (exists($node/parent::*)) then local:get-ancestors-or-self($node/parent::*) else () }; -- How to use it with your $datum variable let $datum := your-target-node-here return local:get-ancestors-or-self($datum)
This function returns all nodes from $datum up to the root element, in the same order as ancestor-or-self::* (current node first, then parent, then grandparent, etc.).
2. Iterative Loop (If Recursion Isn't Preferred)
If your environment has limitations on recursion, you can build the list iteratively by tracking the current parent node and adding it to the result set step by step:
let $datum := your-target-node-here let $result := ($datum) let $current-parent := $datum/parent::* return if (exists($current-parent)) then -- Append the parent's ancestor chain to the result $result || local:get-ancestors-or-self($current-parent) else $result
For a pure loop approach (ideal if recursion is blocked), you can use a for loop with a maximum depth (adjust based on your document's structure):
let $datum := your-target-node-here let $max-depth := 10 -- Tweak this to match your document's deepest possible hierarchy return ($datum) || for $i in 1 to $max-depth let $node := $datum/(../)*[$i] where exists($node) return $node
3. Shorthand Parent Traversal (For Fixed Depth)
If you only need to traverse a known number of levels up, use the ../ shorthand for parent nodes directly:
let $datum := your-target-node-here return ($datum, $datum/.., $datum/../.., $datum/../../..)
This is quick but not flexible for documents with variable depth.
Quick Check: Try the Function Form
Some environments block the axis syntax but still support the standard fn:ancestor-or-self() function. Give this a shot first—it's the simplest fix if it works:
let $datum := your-target-node-here return fn:ancestor-or-self($datum)
If none of these work, sharing a bit more about your specific XQuery environment (like which processor or version you're using) could help narrow down even more targeted solutions.
内容的提问来源于stack exchange,提问作者ncrouch25

