Page 1 of 1

function parameter - enforce xsi:type

Posted: Tue Jan 03, 2012 6:24 pm
by sandrocchio_0.1
I am trying to use the following signature in my xquery function

Code: Select all


declare namespace cdm-base  = "http://cdm.basic.upc.com";

...

declare function common:isMainProduct(
$product as element(*,cdm-base:ProductComponent)
....
just to make sure I got the right @xsi:type.

Now, I am using Oxygen 13.0 where I get
F [Saxon-EE XQuery 9.3.0.5] No schema has been imported for namespace "http://cdm.basic.upc.com";
I have tried replacing the xsd declaration with

Code: Select all


import schema namespace cdm-base = "file:///Workspace/trunk/common/schema/cdm-basic.xsd";
or even setting up the xsd location with a catalog.xml

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="http://cdm.basic.upc.com" uri="file:///Workspace/trunk/common/schema/cdm-basic.xsd"/>
</catalog>
no luck :?

Any ideas?
Thanks in advance

Re: function parameter - enforce xsi:type

Posted: Wed Jan 04, 2012 2:06 pm
by sandrocchio_0.1

Re: function parameter - enforce xsi:type

Posted: Wed Jan 04, 2012 6:03 pm
by adrian
Hi,

To clarify this for other forum members, the syntax for importing a schema is:

Code: Select all

import schema namespace <prefix> = <namespaceURI> at <schemaURI>;
In your case that translates to:

Code: Select all

import schema namespace cdm-base = "http://cdm.basic.upc.com" at "file:///Workspace/trunk/common/schema/cdm-basic.xsd";
Regards,
Adrian

Re: function parameter - enforce xsi:type

Posted: Wed Jan 04, 2012 7:45 pm
by sandrocchio_0.1
I am still having some difficulties in defining a function signature with parameters schema aware.

I now have

Code: Select all


import schema namespace cdm-base="http://cdm.basic.upc.com" at "file:///trunk/common/schema/cdm-basic.xsd";
declare namespace se-al = "http://al.service.upc.com";
declare function common:getProduct(
$item as element(cdm-base:upcProductOrderItem),
$request as element(se-al:submitOrderRequest)
) as element(*,cdm-base:ProductComponent) {
common:resolveElement($item/*[fn:starts-with(local-name(.),'product')=fn:true()], $request)
xsd

Code: Select all


<xs:complexType name="ProductComponent" abstract="false">
<xs:annotation>
<xs:documentation source="description">A type of Product that has no subordinate Product(s), that is, a Product Component is a leaf level Product.</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="cdm:Product"/>
</xs:complexContent>
xml

Code: Select all


<cdm-basic:product xmlns:cdm-basic="http://cdm.basic.upc.com" xsi:type="cdm-basic:ProductComponent" idRefKey="Ref-10495457">
Engine name: Saxon-EE XQuery 9.3.0.5
Severity: error
Description: Required item type of result of function common:getProduct() is element(*, ProductComponent); supplied value has item type {http://cdm.basic.upc.com}product
Start location: 118:0
URL: http://www.w3.org/TR/xpath20/#ERRXPTY0004
Now, I am sure the function works properly because I've been using for a while only specifying the element name, which doesn't require any schema import. Now I have a new requirement, such elements will always have same type but in turn they may also have different names and I want to enforce this check trough the function signature.


The strange thing is I do not have any error while typing, it pops up during transformation only.

Re: function parameter - enforce xsi:type

Posted: Thu Jan 05, 2012 12:32 pm
by adrian
It's not a syntax error, it's a runtime error(wrong item type in return), that's why you only see it at transformation time.

The error indicates the returned item type from common:getProduct() is of a type different from the one specified.
Does common:getProduct return the result of common:resolveElement()?
What item type does the common:resolveElement function return?

Regards,
Adrian

Re: function parameter - enforce xsi:type

Posted: Thu Jan 05, 2012 1:14 pm
by sandrocchio_0.1

Code: Select all


declare function common:resolveElement(
$anyElem as element(),
$request as element(se-al:submitOrderRequest)
) as element()+ {
if(fn:ends-with(fn:local-name($anyElem),"Ref")=fn:true()) then common:getElementByIdRefKey($request,$anyElem/text())
else $anyElem
}
This function simply checks and eventually resolve any element reference, it does not care on the element type.

Re: function parameter - enforce xsi:type

Posted: Thu Jan 05, 2012 5:21 pm
by sandrocchio_0.1
to me sounds more like it trying to match the Qname with the type

Re: function parameter - enforce xsi:type

Posted: Thu Jan 05, 2012 5:33 pm
by adrian
common:resolveElement() returns an indeterminate item type depending on the result of the if statement. Either:
- common:getElementByIdRefKey($request,$anyElem/text())
or
- $anyElem

This result is then returned by common:getProduct() which must have the fixed item type: element(*,cdm-base:ProductComponent).
My guess is that common:resolveElement() does not return an item of the appropriate type: element(*,cdm-base:ProductComponent).

Have you tried using the XQuery debugger(with Saxon-EE) to follow(XWatch) the results/types of these functions?

Regards,
Adrian

Re: function parameter - enforce xsi:type

Posted: Thu Jan 05, 2012 6:54 pm
by sandrocchio_0.1

Code: Select all


declare function local:matchType(
$input as element()
) as element(*,cdm-base:ProductComponent) {
<cdm-base:product xsi:type="cdm-base:ProductComponent" />

};
while typing
F [Saxon-EE XQuery 9.3.0.5] Required item type of result of function local:matchType() is element(*, ProductComponent); supplied value has item type element({http://cdm.basic.upc.com}product, {http://www.w3.org/2001/XMLSchema}untyped)
:?