Namespaces in YADIS Capabilities Documents
Michael Graves
groupmg at gmail.com
Thu Nov 24 21:05:12 PST 2005
First, I've been typing out "YADIS Capabilities Document" so much of late that
the obvious acronym is unavoidable - YDC.
Over on ID sandbox
(http://blog.idsandbox.com/articles/2005/11/25/first-yadis-enabled-logins) I
have a post that describes a new feature of the ID Sandbox: a "YADIS consumer".
The page here:
http://yadis.idsandbox.com/yadis/login_test
Implements login via YADIS riding on top of OpenID. Check it out if you're
interested (you may need to read the blog post to get your own OpenID accounts
configured to use with the Login Tester.)
Anyway, the reason for this post is bring up an issue that may have already come
up, but which I'd like to weigh in on, having just written code that attempts to
actually implement YADIS discovery. The YDC, whatever the governing XML schema
is, should support namespaces for the capabilities that are listed within it.
For example, here is the fragment I'm using to configure the YADIS Login Tester
to use OpenID for login:
<Service xmlns="http://openid.net/">
<Type version="1.0">http://openid.net/</Type>
<oi:server>http://videntity.org/server</oi:server>
<oi:delegate>http://mgraves.videntity.org/</oi:delegate>
</Service>
You can see I've injected namespace usage into the <Service> tag.
Why?
When a consumer is trying to identify needed capabilities for a YADIS ID, the
YDC can be difficult to parse and extract the desired elements if namespaces
aren't used. If I'm looking for an OpenID server, my consumer code might be (and
was) confused if it found <server> tags for both OpenID services, and other
services. <server> is an obvious candidate for overloading in a YDC, and I've
already been bit by it.
Since every <Service> declares a unique and defining URI, (via the <Type> tag),
everything else within the <Service> tag is capability-specific. That means each
service will have (potentially) it's own "vocabulary" of configuring info, and
the tags used from one <Service> can and will clash with tags from a completely
different <Service>.
Using namespaces solved the problem for me. A namespace defined for a service is
a built-in way to "scope" the child elements in such a way that they are quickly
and reliably found. I now can use XPath on my YDCs to quickly extract all the
"oi:server" elements, and they won't be confused with non OpenID <xyz:server> or
<server> tags, as I'm telling XPath to only looking for <oi:server> elements
within the appropriate namespace.
So, think about namespaces for the YDC, and also this: if a <Service> tag has a
URI (the <Type> tag), isn't the capability URI a *de facto* namespace? If so,
shouldn't we consider moving the <Type> tag into an XML namespace declaration:
<Service xmlns:oi="http://openid.net/">
That way, any child tags are unambiguously and quickly found via XPath and
trivial XML parsing. If I'm scanning with XPath, and namespaces are used, I
*know* that <oi:server> is an OpenID server identifier if I know that the
enclosing <Service> has the "oi" namespace bound to OpenID.
-Mike
More information about the yadis
mailing list