-
Notifications
You must be signed in to change notification settings - Fork 63
Namespaces and Namespace Prefixes
Questions frequently come up in the Hydra community about XML namespaces, namespace prefixes, and XPath. This page will attempt to resolve some of the confusion that comes up without diving too deep into the guts of XML.
A namespace prefix is a shorthand placeholder for a thing, not the thing itself. The prefix only exists within a certain scope, while the namespace itself is durable. For example, the following two RDF documents are equivalent:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:ns0="http://projecthydra.org/ns/relations#"
xmlns:ns1="info:fedora/fedora-system:def/model#"
xmlns:ns2="info:fedora/fedora-system:def/relations-external#">
<rdf:Description rdf:about="info:fedora/avalon:1212">
<ns0:hasModelVersion>R3</ns0:hasModelVersion>
<ns1:hasModel rdf:resource="info:fedora/afmodel:MasterFile"/>
<ns2:isPartOf rdf:resource="info:fedora/avalon:1211"/>
</rdf:Description>
</rdf:RDF>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="info:fedora/avalon:1212">
<hasModelVersion xmlns="http://projecthydra.org/ns/relations#">R3</hasModelVersion>
<hasModel xmlns="info:fedora/fedora-system:def/model#"
rdf:resource="info:fedora/afmodel:MasterFile"/>
<isPartOf xmlns="info:fedora/fedora-system:def/relations-external#"
rdf:resource="info:fedora/avalon:1211"/>
</rdf:Description>
</rdf:RDF>
while this third one is not:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="info:fedora/avalon:1212">
<hasModelVersion>R3</hasModelVersion>
<hasModel rdf:resource="info:fedora/afmodel:MasterFile"/>
<isPartOf rdf:resource="info:fedora/avalon:1211"/>
</rdf:Description>
</rdf:RDF>
In the first example, all four XML namespaces are assigned prefixes on the root element of the document. In the second, each predicate is assigned its namespace as a scoped default (applying only to that element and its children). In the third, all predicate-specific namespaces are removed, destroying the semantic meaning of those predicates, because an XML element's identity is a combination of its namespace URI (not prefix!) and its name.
All of the following are true:
- The XPath query
//ns1:hasModel
will raise an error against any of these three documents unless the XPath engine (not the document) knows thatns1
is a placeholder for the namespace URIinfo:fedora/fedora-system:def/model#
. - The XPath query
//fedora-model:hasModel
will find thehasModel
assertions in the first two documents, provided the XPath engine has definedfedora-model
as a prefix forinfo:fedora/fedora-system:def/model#
. - The XPath query
//hasModel
will do one of three things:
- If the XPath engine's default namespace has been set to
info:fedora/fedora-system:def/model#
, it will find thehasModel
assertions in the first two documents as expected. - If the XPath engine's default namespace is undefined, it will find only the
hasModel
assertion in the third document, but it won't mean the same thing to ActiveFedora because the namespace is missing. - If the XPath engine's default namespace is set to something else, it will return an empty result set.
- The XPath query
//*[local-name()="hasModel"]
tells the XPath engine to ignore namespaces and find all elements with the local namehasModel
. It will find all threehasModel
assertions, but the third one won't mean the same thing as the first two. Trust me, you don't want to do this. - The XPath query
//*[local-name()="hasModel" and namespace-uri()="info:fedora/fedora-system:def/model#"]
will work exactly like example 2 above, regardless of which namespaces the XPath engine knows about.