Re: XPath + namespace prefixes in key/keyref

Hi Saul,

> However, I'm unable to assume anything about the prefix abbreviation
> that will be associated with the namespaces "http://me.com/listns"
> and "http://me.com/groupns"...because this xml fragment is actually
> a message passed to me (therefore I don't get to assume that 'gr' is
> the prefix associated with "http://me.com/groupns"). So I face the
> question of what to put into the xpath attribute of the key and
> keyref schema-elements (which must obviously be children of the
> <document> schema-description).

Namespace-aware processing is built around the understanding that you
cannot assume anything about the prefix associated with a particular
namespace. All you have to know is the namespace; you use whatever
prefix you like in your particular document and it means the same
thing as if you'd used a completely different prefix. XML Schema and
XPath are both namespace aware, so they naturally support this kind of
thing.

> My attempts were:
>
> 1)  Use the local-name() function of Xpath.  like this:
[snip]
> However, Xerces barfs on the '[' character in the xpath
> attribute...and besides, this isn't really a good solution, I don't
> think.

You're right that it's not a good solution anyway, but Xerces barfs on
the '[' character because XML Schema uses a restricted form of XPath
that doesn't include predicates, so it's impossible to do it this way.

> 2)  declare the namespace-prefix that I want right next to the xpath
> element

This should work, although there's also nothing stopping you from
putting the namespace declarations on the xs:schema element (which I
think makes it easier to read). The thing that might be causing
problems is the keyref identity constraint:

>     <xs:keyref name="thisStringDoesntMatter"
>                refer="tns:layerDefinitionKey">
>       <xs:selector xpath="gr:groupList/*//gr:group"
>                    xmlns:gr="http://me.com/groupns" />
>       <xs:field xpath="@id"/>
>     </xs:keyref>

This is scoped within the document. It selects all the group elements
that are descendants of an element that is a child of a groupList
element that is a child of the document element, and uses their id
attributes. It looks as if the group elements don't have id
attributes, from your example.

In your example, you were interested in the ids of the object elements
that were children of the group elements that were children of the
groupList element, so you should have something like:

  <xs:keyref name="thisStringDoesntMatter"
             refer="tns:layerDefinitionKey">
    <xs:selector xpath="gr:groupList/gr:group/tns:object"
                 xmlns:gr="http://me.com/groupns" />
    <xs:field xpath="id" />
  </xs:keyref>

The step to the object element has to include the 'tns' prefix (which
I assume is associated with the namespace 'http://me.com/documentns'
because the object elements are in the 'http://me.com/documentns'
namespace. In XPaths, not having a prefix would put them in no
namespace.

The above works in XSV - I get an error when there's an object
element whose id is not the same as the id of an uniqueObject
element.
  
I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/

Received on Monday, 5 November 2001 12:44:29 UTC