XQuery自定义函数my-remove-elements报错err:XPTY0004求解
Let's break down those frustrating err:XPTY0004 errors and get your my-remove-elements function working correctly to keep only first_name and last_name attributes in your employees.xml document.
Understanding the Errors
First, let's unpack what each error means:
- "is not a sub-type of element()": This usually happens when your function expects an element node as input, but you're passing something else (like attribute nodes, text nodes, or a sequence that includes non-element items). Or you might be trying to perform element-specific operations on non-element nodes inside the function.
- "The actual cardinality for parameter 1 does not match the cardinality in the function's signature": Cardinality refers to how many items a sequence contains (zero, one, or many). This error pops up when your function expects, say, a single element (
element()) but you pass a sequence of multiple elements (element()*), or vice versa.
Correct Function Implementation
Here's a revised version of your function that addresses both issues. It's designed to process a sequence of elements, retain only the first_name and last_name attributes, and preserve the original element structure (plus any child nodes if you need them):
declare function local:my-remove-elements($elements as element()*) as element()* { for $elem in $elements return element { node-name($elem) } { -- Keep only the desired attributes $elem/@first_name, $elem/@last_name, -- Optional: retain child nodes of the original element (remove this line if you don't need them) $elem/node() } }; -- Example call (assuming your XML has a root <employees> with <employee> child elements) local:my-remove-elements(/employees/employee)
Fixing the First Error ("not a sub-type of element()")
The most common cause here is passing the wrong kind of node to your function:
- Double-check your function call: Make sure you're passing element nodes (like
/employees/employee) not attribute nodes (like/employees/employee/@*). If you pass attributes directly to a function expecting elements, you'll get this type mismatch error. - Verify your function parameter type: If you accidentally declared the parameter as
attribute()instead ofelement(), that would also trigger this error. The code above useselement()*to accept any number of element nodes.
Fixing the Cardinality Mismatch Error
This is all about matching the number of items your function expects vs. what you pass:
- If your original function declared the parameter as
element()(single element only), but you're passing multiple employee elements (a sequence), that's the problem. Changing the parameter type toelement()*(zero or more elements) fixes this, as shown in the code above. - Similarly, if your function's return type was
element()(single element) but you're generating multiple elements, update it toelement()*to match the output cardinality.
Quick Test with Sample XML
To verify, use a small snippet of your employees.xml like this:
Running the function call above will return each <employee> element with only the first_name and last_name attributes, stripping out the others.
内容的提问来源于stack exchange,提问作者Judah Flynn

