Resolving a Part Name from a Target URI

This topic shows how to use the Packaging APIs to resolve a part name from the URI of a relationship target.

This topic contains the following sections.

Introduction

The following code example shows the details of the ResolveTargetUriToPart function, which resolves a part name from the URI of a relationship's target.

ResolveTargetUriToPart is declared in the opclib.h header file and defined in the opclib.cpp implementation file of the Set Author Sample. For the complete program, which can load, modify, and save a package, see the Set Author Sample.

Resolving a Part Name from a Relationship Target URI

In the following sections, the ResolveTargetUriToPart function checks the relationship's target mode to confirm that the target is a part. Next, the target URI and source URI of the relationship are retrieved and used to resolve the part name.

The ResolveTargetUriToPart function declaration from opclib.h:

HRESULT
    ResolveTargetUriToPart(
    IOpcRelationship * relativeUri,
    IOpcPartUri **resolvedUri
    );

Steps to Resolve a Part Name

  1. Declare variables that will be used to resolve the part name:

        IOpcUri * sourceUri = NULL;
        IUri * targetUri = NULL;
        OPC_URI_TARGET_MODE targetMode;
    
  2. Get the target mode of the relationship:

        // Get the target mode of the relationship.
        HRESULT hr = relationship->GetTargetMode(&targetMode);
    
  3. If the target mode is external, the relationship does not target a part and the function fails:

        if (SUCCEEDED(hr) && targetMode != OPC_URI_TARGET_MODE_INTERNAL)
        {
            // The target mode of the relationship was not internal.
            // Function fails because the relationship does not target a part
            // therefore, no part name can be resolved.
            hr = E_FAIL;
        }
    

    Relationships that target parts use the internal target mode.

  4. Get the URI of the relationship  target:

        if (SUCCEEDED(hr))
        {
            // Get a URI for the relationship's target. This URI might be
            // relative to the source of the relationship.
            hr = relationship->GetTargetUri(&targetUri);
        }
    

    The URI that is retrieved is relative to the URI of the relationship's source.

  5. Get the URI of the relationship  source, as shown in the following code.

        if (SUCCEEDED(hr))
        {
            // Get the URI for the relationship's source.
            hr = relationship->GetSourceUri(&sourceUri);
        }
    

    If the source of the relationship is a part, the URI retrieved will be a part name. Otherwise, the source is the package itself and the retrieved URI is the package root.

  6. Resolve the part name by calling the IOpcUri::CombinePartUri method, as shown in the following code.

        if (SUCCEEDED(hr))
        {
            // Form the API representation of the resultant part name.
            hr = sourceUri->CombinePartUri(targetUri, resolvedUri);
        }
    
        // Release resources
        if (sourceUri)
        {
            sourceUri->Release();
            sourceUri = NULL;
        }
    
        if (targetUri)
        {
            targetUri->Release();
            targetUri = NULL;
        }
    
    

    IOpcUri::CombinePartUri uses the URI in sourceUri as the base URI, and resolves the relative URI in targetUri against it.

ResolveTargetUriToPart Code Details

The following code shows the ResolveTargetUriToPart function definition in one convenient block, found opclib.cpp.

The ResolveTargetUriToPart function definition:

HRESULT
ResolveTargetUriToPart(
    IOpcRelationship *relationship,
    IOpcPartUri **resolvedUri
    )
{
    IOpcUri * sourceUri = NULL;
    IUri * targetUri = NULL;
    OPC_URI_TARGET_MODE targetMode;

    // Get the target mode of the relationship.
    HRESULT hr = relationship->GetTargetMode(&targetMode);
    if (SUCCEEDED(hr) && targetMode != OPC_URI_TARGET_MODE_INTERNAL)
    {
        // The target mode of the relationship was not internal.
        // Function fails because the relationship does not target a part
        // therefore, no part name can be resolved.
        hr = E_FAIL;
    }
    // Get the segments of the URI and turn it into a valid part URI.
    // The target should be resolved against the source URI of the 
    // relationship to expand relative URIs into part URIs with absolute 
    // paths.
    if (SUCCEEDED(hr))
    {
        // Get a URI for the relationship's target. This URI might be
        // relative to the source of the relationship.
        hr = relationship->GetTargetUri(&targetUri);
    }
    if (SUCCEEDED(hr))
    {
        // Get the URI for the relationship's source.
        hr = relationship->GetSourceUri(&sourceUri);
    }
    if (SUCCEEDED(hr))
    {
        // Form the API representation of the resultant part name.
        hr = sourceUri->CombinePartUri(targetUri, resolvedUri);
    }

    // Release resources
    if (sourceUri)
    {
        sourceUri->Release();
        sourceUri = NULL;
    }

    if (targetUri)
    {
        targetUri->Release();
        targetUri = NULL;
    }

    return hr;
}

Disclaimer

Code examples are not intended to be complete and working programs. The code examples that are referenced on this page, for example, do not perform parameter checking, error checking, or error handling. Use these examples as a starting point, then add the code necessary to create robust application. For more information about error handling in COM, see the Error Handling (COM) topic.

Parts How-To Topics

Overviews

Finding the Core Properties Part

Getting Started with the Packaging API

Parts Overview

Reference

Packaging API Reference

Packaging API Samples

Set Author Sample

Set Author opclib.h

Set Author opclib.cpp