DOM guide: Resolving URIs: Difference between revisions

From COLLADA Public Wiki
Jump to navigation Jump to search
Alorino (talk | contribs)
No edit summary
Elf (talk | contribs)
copy editing & fmtg
Line 1: Line 1:
The <code>daeURI</code> class represents URI data types in the [[COLLADA DOM]]. The <code>daeURI</code> class provides an interface for accessing/manipulating the URI string and for resolving the URI reference.
The <code>daeURI</code> class represents [[URI]] data types in the [[COLLADA DOM]]. The <code>daeURI</code> class provides an interface for accessing/manipulating the URI string and for resolving the URI reference.


==Working with daeURI==
==Working with daeURI==
The COLLADA DOM uses normalized absolute URIs only. The daeURI class contains code that converts relative URIs into absolute URIs.
The COLLADA DOM uses normalized absolute URIs only. The '''daeURI''' class contains code that converts relative URIs into absolute URIs.


The base URI syntax is
The base URI syntax is:
  scheme://authority/filepath?query#fragment
  scheme://authority/filepath?query#fragment


An absolute URI contains a scheme and an authority. If the authority is left empty than <code>localhost</code> is used, i.e.
An '''absolute URI''' contains a scheme and an authority. If the authority is left empty than <code>localhost</code> is used. For example:
  file:///c:/path/document.dae#Geo_01
  file:///c:/path/document.dae#Geo_01
is a URI that references a file named document.dae on the localhost found in c:/path.
is a URI that references a file named '''document.dae''' on the localhost found in '''c:/path'''.


The fragment portion is used to identify elements by using their "id" attribute. The previous example references an element with an id "Geo_01".
The ''fragment'' portion is used to identify elements by using their "id" attribute. The previous example references an element with an id "Geo_01".


A relative URI is any URI that does not contain a scheme and authority.
A ''relative URI'' is any URI that does not contain a scheme and authority. A relative URI can be a relative path, an absolute path, or just a fragment.
 
A relative URI can be a relative path, an absolute path, or just a fragment.


Examples of relative path URIs:
Examples of relative path URIs:
Line 28: Line 26:
  #redMaterial
  #redMaterial


The COLLADA DOM parses URI strings and normalizes them into absolute URIs before it can use the URI for any operation, i.e. load or resolveElement.
The COLLADA DOM parses URI strings and normalizes them into absolute URIs before it can use the URI for any operation, such as '''load''' or '''resolveElement'''.


A base URI is needed to normalize relative URIs. Absolute URIs do not require a separate base URI. The COLLADA DOM will provide a base URI. If the URI is found within a COLLADA document then the base URI will be the document URI. If the URI is not part of a document then the current working directory is used as the base URI.
A base URI is needed to normalize relative URIs. Absolute URIs do not require a separate base URI. The COLLADA DOM provides a base URI. If the URI is found within a COLLADA document then the base URI is the document URI. If the URI is not part of a document then the current working directory is used as the base URI.


Assuming a base URI of
Assuming a base URI of
  file:///c:/A/B/C/D/doc.dae
  file:///c:/A/B/C/D/doc.dae
here are some examples of how the following URIs will be normalized:
here are some examples of how the following URIs will be normalized:
./path/document.dae                  => file:///c:/A/B/C/D/path/document.dae
{| border=1 cellspacing=0 cellspacing=4
../../../path/document.dae#elementID  => file:///A/path/document.dae#elementID
|-
/c:/path/document.dae#Light01        => file:///c:/path/document.dae#Light01
!Original URI||Normalized URI
c:/path/document.dae                  => file:///c:/A/B/C/D/c:/path/document.dae
|-
| ./path/document.dae                  || file:///c:/A/B/C/D/path/document.dae
|-
| ../../../path/document.dae#elementID  || file:///A/path/document.dae#elementID
|-
|/c:/path/document.dae#Light01        || file:///c:/path/document.dae#Light01
|-
| c:/path/document.dae                  || file:///c:/A/B/C/D/c:/path/document.dae
|}
 
 
'''''Note:''' Windows file paths '''are not''' proper absolute path relative URIs!''


Note that '''Windows file paths ARE NOT proper absolute path relative URIs!'''
Note also that only the slash (/) character is used as a path delimeter. Windows uses the backslash (\) to delimit path segments. Using the backslash can result in incorrect URI processing! "A\B\C" is considered one path segment. If using "file:///A\B\C" as a base URI and trying to resolve "../doc.dae" the result will be "file:///doc.dae" and ''not'' "file:///A\B\doc.dae" as one might have expected.  
Note also that only the '/' character is used as a path delimeter. Windows uses the '\' character to delimit path segments. Using '\' character can result in incorrect URI processing! "A\B\C" is considered one path segment. If using "file:///A\B\C" as a base URI and trying to resolve "../doc.dae" the result will be "file:///doc.dae" and NOT "file:///A\B\doc.dae" as one might have expected.  


===Accessing URI Data===
===Accessing URI Data===
The daeURI class provides accessors to all of the parts of a parsed URI. Please note that the COLLADA DOM refers to the "scheme" as "protocol" and the fragment as "id".
The '''daeURI''' class provides accessors to all of the parts of a parsed URI. Note that the COLLADA DOM refers to the "scheme" as "protocol" and the fragment as "id".


Calling daeURI::getURI will return the full URI string. This may be the non-normalized URI string if getURI is called before the URI is normalized. URIs are normalized when they are needed for an operation, i.e. resolveElement or loading a document.
Calling '''daeURI::getURI'''  returns the full URI string. This may be the nonnormalized URI string if '''getURI''' is called before the URI is normalized. URIs are normalized when they are needed for an operation, for example, in '''resolveElement''' or when loading a document.


Calling daeURI::getOriginalURI will return the original URI string either read from the document or supplied by the user before the URI was normalized.
Calling '''daeURI::getOriginalURI''' returns the original URI string either read from the document or supplied by the user before the URI was normalized.


daeURI::getContainer will return a reference to the element that contains this URI data. This is helpful if you are given a daeURI object and need to find it's context or check which document it belongs to.
'''daeURI::getContainer''' returns a reference to the element that contains this URI data. This is helpful if you are given a '''daeURI''' object and need to find its context or check which document it belongs to.


===Resolving URIs===
===Resolving URIs===
As part of the document loading process, the COLLADA DOM will attempt to resolve all of the URIs that are loaded.
As part of the document loading process, the COLLADA DOM attempts to resolve all of the URIs that are loaded.


The element that a URI resolves to, if successful, can be retrieved by calling daeURI::getElement.
The element that a URI resolves to, if successful, can be retrieved by calling '''daeURI::getElement'''.


If daeURI::getElement returns NULL then there could have been an error attempting to resolve the URI or there hasn't been an attempt at all. Calling daeURI::getState will tell you the status of the URI. If getState returns a value of uri_failed_* then there was an error resolving the URI. If getState returns uri_pending then there hasn't been an attempt to resolve the URI.
If '''daeURI::getElement''' returns NULL then there could have been an error attempting to resolve the URI or there hasn't been an attempt at all. Calling '''daeURI::getState'''  provides the status of the URI. If '''getState''' returns a value of '''uri_failed_*''' then there was an error resolving the URI. If '''getState''' returns ''uri_pending''' then there hasn't been an attempt to resolve the URI.


To resolve a URI call daeURI::resolveElement.  
To resolve a URI, call '''daeURI::resolveElement'''.  


All URIs that are found in a document upon load will attempt to resolve, but if an application creates elements programattically you may encounter URIs that are in the uri_pending unresolved state. To be safe, you should always check daeURI::getElement for NULL and if NULL, check the state and if needed attempt to resolve the URI manually by calling daeURI::resolveElement.
All URIs that are found in a document upon load will attempt to resolve, but if an application creates elements programattically, you may encounter URIs that are in the '''uri_pending''' unresolved state. To be safe, you should always check '''daeURI::getElement''' for NULL and, if NULL, check the state and, if needed, attempt to resolve the URI manually by calling '''daeURI::resolveElement'''.


If there have been many elements that have been created calling daeElement::resolveAll will resolve all URIs that are present in those newly created elements. An application that creates new elements and intends to pass COLLADA DOM data between different systems, like a conditioner in the [[COLLADA Refinery]], would benefit from calling daeElement::resolveAll before finishing. This could avoid common errors in which applications assume all URIs have attempted to be resolved.
If there have been many elements that have been created, calling '''daeElement::resolveAll'' will resolve all URIs that are present in those newly created elements. An application that creates new elements and intends to pass COLLADA DOM data between different systems, like a conditioner in the [[COLLADA Refinery]], would benefit from calling '''daeElement::resolveAll''' before finishing. This could avoid common errors in which applications assume that all URIs have attempted to be resolved.


===Creating URI Strings===
===Creating URI Strings===
The COLLADA DOM provides two ways to create URI strings; by setting the string directly with daeURI::setURI or by using the daeURI::resolveURI method.
The COLLADA DOM provides two ways to create URI strings; by setting the string directly with '''daeURI::setURI''' or by using the '''daeURI::resolveURI''' method.


Calling daeURI::setURI allows you to pass in a new URI string to be used for the daeURI. The daeURI class will parse this string right away but will not normalize the new URI until it is needed. You may set the URI to any valid URI string, absolute or relative. Most commonly URIs are set to reference other COLLADA elements.  
Calling '''daeURI::setURI''' allows you to pass in a new URI string to be used for the '''daeURI'''. The '''daeURI''' class parses this string right away but does not normalize the new URI until it is needed. You may set the URI to any valid URI string, absolute or relative. Most commonly, URIs are set to reference other COLLADA elements.  
*Passing in a string "#''elementID''" will create a URI that references the ''elementID'' element from within the same document.
*Passing in a string "#''elementID''" creates a URI that references the ''elementID'' element from within the same document.
*Passing in a string "''rel-path''/''document''#''elementID''" will create a URI that references an element in an external document.
*Passing in a string "''rel-path''/''document''#''elementID''" creates a URI that references an element in an external document.
Note. It is the clients responsibility to ensure that strings passed into daeURI::setURI are valid URI strings.
'''''Note:''' It is the client's responsibility to ensure that strings passed to '''daeURI::setURI''' are valid URI strings.''


Calling daeURI::resolveURI will create a URI string based on the element set with daeURI::setElement. The COLLADA DOM will create the URI based on the element's documentURI and the element's ID. This method of setting URI strings is very helpful if you have a reference to the element you wish to make the URI reference. Doing so will prevent the need of custom URI string generation. Here is an example of how this works:
Calling '''daeURI::resolveURI'''  creates a URI string based on the element set with '''daeURI::setElement'''. The COLLADA DOM creates the URI based on the element's ''documentURI'' and the element's ''ID''. This method of setting URI strings is very helpful if you have a reference to the element you wish to make the URI reference. Doing so makes custom URI string generation unnecessary. Here is an example of how this works:
  //inst_geom is a pointer to an existing domInstance_geometry element
  //inst_geom is a pointer to an existing domInstance_geometry element
  //geom is a pointer to an existing domGeometry element.
  //geom is a pointer to an existing domGeometry element.
Line 80: Line 88:


==External URI References==
==External URI References==
By default, the COLLADA DOM will load additional COLLADA documents to resolve external URI references. I will be refering to these COLLADA documents as "external documents". Client applications may want or need finer control over which documents are loaded and when.
By default, the COLLADA DOM loads additional COLLADA documents to resolve external URI references. I will refer to these COLLADA documents as ''external documents''. Client applications may want or need finer control over which documents are loaded and when.


The COLLADA DOM provides this functionality with daeURIResolver::setAutoLoadExternalDocuments and various methods of daeDocument class. To disable the DOM from implicitely loading documents when resolving URIs you must call
The COLLADA DOM provides this functionality with '''daeURIResolver::setAutoLoadExternalDocuments''' and various methods of '''daeDocument''' class. To disable the DOM from implicitely loading documents when resolving URIs, you must call
  daeURIResolver::setAutoLoadExternalDocuments( false );
  daeURIResolver::setAutoLoadExternalDocuments( false );
sometime before you attempt to load a document.
sometime before you attempt to load a document.


All URIs that reference elements in external documents will not be resolved. You will be returned the value uri_failed_external_document when querying the status of the URI by calling daeURI::getState.
All URIs that reference elements in external documents will not be resolved. You will be returned the value '''uri_failed_external_document''' when querying the status of the URI by calling '''daeURI::getState'''.


Use daeDocument::getReferencedDocuments to retrieve a list of all documents that the current document has external URI references to.
Use ''daeDocument::getReferencedDocuments''' to retrieve a list of all documents that the current document has external URI references to.


Use daeDocument::getExternalURIs to retrieve a list of pointers to the daeURI objects that reference a specific document.
Use '''daeDocument::getExternalURIs''' to retrieve a list of pointers to the daeURI objects that reference a specific document.


When a new document is loaded into the COLLADA DOM, via DAE::load, the COLLADA DOM checks if any currently loaded documents contain any external references to the newly loaded document. If a document does contain an external reference to the newly loaded document the reference is resolved.
When a new document is loaded into the COLLADA DOM, via '''DAE::load''', the COLLADA DOM checks whether any currently loaded documents contain any external references to the newly loaded document. If a document does contain an external reference to the newly loaded document the reference is resolved.


[[Category:DOM project|Resolving URIs]]
[[Category:DOM project|Resolving URIs]]

Revision as of 03:24, 27 March 2007

The daeURI class represents URI data types in the COLLADA DOM. The daeURI class provides an interface for accessing/manipulating the URI string and for resolving the URI reference.

Working with daeURI

The COLLADA DOM uses normalized absolute URIs only. The daeURI class contains code that converts relative URIs into absolute URIs.

The base URI syntax is:

scheme://authority/filepath?query#fragment

An absolute URI contains a scheme and an authority. If the authority is left empty than localhost is used. For example:

file:///c:/path/document.dae#Geo_01

is a URI that references a file named document.dae on the localhost found in c:/path.

The fragment portion is used to identify elements by using their "id" attribute. The previous example references an element with an id "Geo_01".

A relative URI is any URI that does not contain a scheme and authority. A relative URI can be a relative path, an absolute path, or just a fragment.

Examples of relative path URIs:

./path/document.dae
../../../path/document.dae#elementID
document.dae#Geo_01

An absolute path must be preceded by a forward slash character '/'. An example:

/c:/path/document.dae#Light01

A fragment identifier references an element that can be found within the same document as the URI. An example of this:

#redMaterial

The COLLADA DOM parses URI strings and normalizes them into absolute URIs before it can use the URI for any operation, such as load or resolveElement.

A base URI is needed to normalize relative URIs. Absolute URIs do not require a separate base URI. The COLLADA DOM provides a base URI. If the URI is found within a COLLADA document then the base URI is the document URI. If the URI is not part of a document then the current working directory is used as the base URI.

Assuming a base URI of

file:///c:/A/B/C/D/doc.dae

here are some examples of how the following URIs will be normalized:

Original URI Normalized URI
./path/document.dae file:///c:/A/B/C/D/path/document.dae
../../../path/document.dae#elementID file:///A/path/document.dae#elementID
/c:/path/document.dae#Light01 file:///c:/path/document.dae#Light01
c:/path/document.dae file:///c:/A/B/C/D/c:/path/document.dae


Note: Windows file paths are not proper absolute path relative URIs!

Note also that only the slash (/) character is used as a path delimeter. Windows uses the backslash (\) to delimit path segments. Using the backslash can result in incorrect URI processing! "A\B\C" is considered one path segment. If using "file:///A\B\C" as a base URI and trying to resolve "../doc.dae" the result will be "file:///doc.dae" and not "file:///A\B\doc.dae" as one might have expected.

Accessing URI Data

The daeURI class provides accessors to all of the parts of a parsed URI. Note that the COLLADA DOM refers to the "scheme" as "protocol" and the fragment as "id".

Calling daeURI::getURI returns the full URI string. This may be the nonnormalized URI string if getURI is called before the URI is normalized. URIs are normalized when they are needed for an operation, for example, in resolveElement or when loading a document.

Calling daeURI::getOriginalURI returns the original URI string either read from the document or supplied by the user before the URI was normalized.

daeURI::getContainer returns a reference to the element that contains this URI data. This is helpful if you are given a daeURI object and need to find its context or check which document it belongs to.

Resolving URIs

As part of the document loading process, the COLLADA DOM attempts to resolve all of the URIs that are loaded.

The element that a URI resolves to, if successful, can be retrieved by calling daeURI::getElement.

If daeURI::getElement' returns NULL then there could have been an error attempting to resolve the URI or there hasn't been an attempt at all. Calling daeURI::getState provides the status of the URI. If getState returns a value of uri_failed_* then there was an error resolving the URI. If getState returns uri_pending then there hasn't been an attempt to resolve the URI.

To resolve a URI, call daeURI::resolveElement.

All URIs that are found in a document upon load will attempt to resolve, but if an application creates elements programattically, you may encounter URIs that are in the uri_pending unresolved state. To be safe, you should always check daeURI::getElement for NULL and, if NULL, check the state and, if needed, attempt to resolve the URI manually by calling daeURI::resolveElement.

If there have been many elements that have been created, calling daeElement::resolveAll will resolve all URIs that are present in those newly created elements. An application that creates new elements and intends to pass COLLADA DOM data between different systems, like a conditioner in the COLLADA Refinery, would benefit from calling daeElement::resolveAll' before finishing. This could avoid common errors in which applications assume that all URIs have attempted to be resolved.

Creating URI Strings

The COLLADA DOM provides two ways to create URI strings; by setting the string directly with daeURI::setURI or by using the daeURI::resolveURI method.

Calling daeURI::setURI allows you to pass in a new URI string to be used for the daeURI. The daeURI class parses this string right away but does not normalize the new URI until it is needed. You may set the URI to any valid URI string, absolute or relative. Most commonly, URIs are set to reference other COLLADA elements.

  • Passing in a string "#elementID" creates a URI that references the elementID element from within the same document.
  • Passing in a string "rel-path/document#elementID" creates a URI that references an element in an external document.

Note: It is the client's responsibility to ensure that strings passed to daeURI::setURI are valid URI strings.

Calling daeURI::resolveURI creates a URI string based on the element set with daeURI::setElement. The COLLADA DOM creates the URI based on the element's documentURI and the element's ID. This method of setting URI strings is very helpful if you have a reference to the element you wish to make the URI reference. Doing so makes custom URI string generation unnecessary. Here is an example of how this works:

//inst_geom is a pointer to an existing domInstance_geometry element
//geom is a pointer to an existing domGeometry element.
inst_geom->getUrl().setElement( geom );
inst_geom->getUrl().resolveURI();

External URI References

By default, the COLLADA DOM loads additional COLLADA documents to resolve external URI references. I will refer to these COLLADA documents as external documents. Client applications may want or need finer control over which documents are loaded and when.

The COLLADA DOM provides this functionality with daeURIResolver::setAutoLoadExternalDocuments and various methods of daeDocument class. To disable the DOM from implicitely loading documents when resolving URIs, you must call

daeURIResolver::setAutoLoadExternalDocuments( false );

sometime before you attempt to load a document.

All URIs that reference elements in external documents will not be resolved. You will be returned the value uri_failed_external_document when querying the status of the URI by calling daeURI::getState.

Use daeDocument::getReferencedDocuments' to retrieve a list of all documents that the current document has external URI references to.

Use daeDocument::getExternalURIs to retrieve a list of pointers to the daeURI objects that reference a specific document.

When a new document is loaded into the COLLADA DOM, via DAE::load, the COLLADA DOM checks whether any currently loaded documents contain any external references to the newly loaded document. If a document does contain an external reference to the newly loaded document the reference is resolved.