Skip to content

Supported CSW Profiles for Synchronization

mhogeweg edited this page Dec 27, 2012 · 3 revisions

If you are want to register a CSW endpoint for federated search or harvest (see How to Publish Resources) you will need to specify what transformation of CSW the geoportal should use to communicate with the remote CSW endpoint. On the Register a Resource on the Network page, after you select the 'CSW' radio button you will see a field called "Profile". This is a dropdown box with many options. Which to choose? If the endpoint you are registering is another Esri Geoportal, you will select "ArcGIS Server Geoportal Extension (GPT)" option from the dropdown. If you are registering a different type of CSW endpoint, you may choose one the profile as specified in the GetCapabilities URL for the CSW endpoint you want to register.

If you do not see a profile that is compatible with your endpoint, you can work with the organization hosting the geoportal to configure support for a new CSW profile. See the Add support for a new profile section below.

Table of Contents

Supported CSW Profiles

The following list describes which CSW Profiles are available out of the box for registering with your geoportal for federated search or synchronization. If a profile is listed but you don't see support for it in the geoportal to which you are trying to register, it is possible that the organization is using an older version of the geoportal where certain profiles are not supported.

  • ArcGIS Server Geoportal Extension (GPT)
  • ArcGIS Server Geoportal Extension (version 10) CSW ISO AP
  • ArcIMS 9.1 CSW 2.0.0 OGCCORE
  • ArcIMS 9.2 CSW 2.0.0 OGCCORE
  • ArcIMS 9.2 CSW 2.0.1 ebRIM
  • ArcIMS 9.2 CSW 2.0.1 OGCCORE
  • ArcIMS 9.2 Post Service Pack 2 CSW 2.0.0 OGCCORE
  • ArcIMS 9.2 Post Service Pack 2 CSW 2.0.1 OGCCORE
  • ArcIMS 9.3 CSW 2.0.2 OGCCORE
  • Compusult WES9 CSW 2.0.0 OGCCORE
  • CSW.OGCCORE.FEMA
  • EXCAT CSW 2.0.2 OGCCORE
  • GeoNetwork CSW 2.0.1 EBRIM
  • GeoNetwork CSW 2.0.1 OGCCORE
  • GeoNetwork CSW 2.0.2 APISO
  • IONIC CSW 2.0.0 ebRIM
  • NASA CSW 2.0.2 APISO
  • OWS-7 CSW 2.0.2 ebRIM
  • SRU CSW 2.0.2 Gateway to Z39.50
  • terra catalog CSW 2.0.2 AP ISO

Add support for a new profile

If you are not able to successfully conduct a federated search or harvest using the available profiles supported in the geoportal, you may need to configure a new profile. Because the configuration files to support your profile need to be hosted on the Geoportal Server web application, you will need to work with the organization hosting the geoportal, providing these files for them.

In this process, you will author three xslt's that are used for communicating with the remote CSW endpoint. These three files define a GetRecords request, a GetRecords response, and a GetRecordById response. After authoring these three xslt files, you must reference them with a new profile entry in the CSWProfiles.xml file. The section below provides details about how to author each xslt, and then how to add the reference to the CSWProfiles.xml file.

Author the GetRecords_Request.xslt

The geoportal applies a transformation that translates the generic XML from the geoportal user interface into a CS-W GetRecordsRequest that the catalog service can interpret. The code snippet below shows a generic GetRecords_Request.xslt with annotation in the commented sections describing details for important parts of the file. Copy this text into a text editor such as Notepad, and make the adjustments described in the comments.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="no" encoding="UTF-8" omit-xml-declaration="yes"/>
  <xsl:template match="/">
    <xsl:element name="csw:GetRecords"
     use-attribute-sets="GetRecordsAttributes"
     xmlns:csw="http://www.opengis.net/cat/csw/2.0.2"
     xmlns:ogc="http://www.opengis.net/ogc"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:gml="http://www.opengis.net/gml">
      <csw:Query typeNames="csw:Record">
        <csw:ElementSetName>full</csw:ElementSetName>
        <csw:Constraint version="1.0.0">
          <ogc:Filter xmlns="http://www.opengis.net/ogc">
            <ogc:And>
              <!-- CSW Client must retrieve the following information to
                define the search the user specifies in the User Interface:
                'KeyWord' corresponds to the search term the user inputs,
                'LiveDataMap' corresponds to if the user specifies "Live Data and
                Maps Only", and 'Envelope' specifies the bounding box for a search
                based on the current extent of the ArcMap window. The 'tmpltDate'
                corresponds to searching a catalog via the geoportal, in the
                Additional Options, Modified Date search on the Search page.
              -->
              <!-- Key Word search --> 
              <xsl:apply-templates select="/GetRecords/KeyWord"/>
              <!-- LiveDataOrMaps search --> 
              <xsl:apply-templates select="/GetRecords/LiveDataMap"/>
              <!-- Envelope search, e.g. ogc:BBOX --> 
              <xsl:apply-templates select="/GetRecords/Envelope"/>
              <!-- Date Range Search --> >
              <xsl:call-template name="tmpltDate"/>
            </ogc:And>
          </ogc:Filter>
        </csw:Constraint>
      </csw:Query>
    </xsl:element>
  </xsl:template>

  <!-- key word search : This template is used to pass the search
    term to the catalog service. The PropertyName 'AnyText' is
    variable, depending on what your catalog service accepts. 'AnyText'
    will search all fields, irrespective of which XML element. If you
    wanted to search only the title or abstract, you could change this
    PropertyName parameter accordingly. The 'PropertyIsLike' elements
    (wildCard="" escape= "" singleChar="") are specific to the CSW
    specification your catalog service follows. 
  -->
  <xsl:template match="/GetRecords/KeyWord"
   xmlns:ogc="http://www.opengis.net/ogc">
    <xsl:if test="normalize-space(.)!=''">
      <ogc:PropertyIsLike wildCard="" escape="" singleChar="">
        <ogc:PropertyName>AnyText</ogc:PropertyName>
        <ogc:Literal>
          <xsl:value-of select="."/>
        </ogc:Literal>
      </ogc:PropertyIsLike>
    </xsl:if>
  </xsl:template>

  <!-- LiveDataOrMaps search: This template is used to pass the
    requirement to retrieve only live data/map records from the catalog
    service. The PropertyName 'Format' depends on the parameter your
    catalog service accepts to define the type of resource the
    resulting record describes. The Literal element "liveData" can be
    changed to indicate the term your service may use to retrieve live
    data records.
  -->
  <xsl:template match="/GetRecords/LiveDataMap"
   xmlns:ogc="http://www.opengis.net/ogc">
    <xsl:if test="translate(normalize-space(./text()),'true', 'TRUE') ='TRUE'">
      <ogc:PropertyIsEqualTo>
        <ogc:PropertyName>Format</ogc:PropertyName>
        <ogc:Literal>liveData</ogc:Literal>
      </ogc:PropertyIsEqualTo>
    </xsl:if>
  </xsl:template>

  <!-- 
    Envelope search: This template is used to define a bounding
    box for resulting records returned from the catalog service if the
    "Use Current Extent" option is selected (ArcMap CSW Client only).
    Resulting records must fall within this bounding box. Do not change
    the PropertyName, Box, or coordinates elements.
  -->
  <xsl:template match="/GetRecords/Envelope" xmlns:ogc="http://www.opengis.net/ogc">
     <!-- generate BBOX query if minx, miny, maxx, maxy are provided -->
     <xsl:if test="./MinX and ./MinY and ./MaxX and ./MaxY">
       <ogc:BBOX xmlns:gml="http://www.opengis.net/gml">
         <ogc:PropertyName>Geometry</ogc:PropertyName>
         <gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
           <gml:coordinates>
             <xsl:value-of select="MinX"/>,<xsl:value-of
              select="MinY"/>,<xsl:value-of
              select="MaxX"/>,<xsl:value-of select="MaxY"/>
            </gml:coordinates>
          </gml:Box>
      </ogc:BBOX>
     </xsl:if>
   </xsl:template>

 <!-- tmpltDate: This template is used to define the date range
 for when resulting records returned from the catalog service were
 modified. This is only used for the geoportal search, and not the
 CSW Client search. This section needs to be included only if you
 want to apply your custom profile to the geoportal itself as well
 as the CSW Client (the custom profile would appear in the dropdown
 list of profiles when a publisher user registers a CSW repository).
 Do not change this section.-->
 <xsl:template name="tmpltDate" xmlns:ogc="http://www.opengis.net/ogc">
   <xsl:if test="string-length(normalize-space(/GetRecords/FromDate/text())) &gt; 0">
     <ogc:PropertyIsGreaterThanOrEqualTo>
       <ogc:PropertyName>Modified</ogc:PropertyName>
       <ogc:Literal>
         <xsl:value-of select="normalize-space(/GetRecords/FromDate/text())"/>
       </ogc:Literal>
     </ogc:PropertyIsGreaterThanOrEqualTo>
   </xsl:if>
   <xsl:if test="string-length(normalize-space(/GetRecords/ToDate/text())) &gt; 0">
     <ogc:PropertyIsLessThanOrEqualTo>
       <ogc:PropertyName>Modified</ogc:PropertyName>
       <ogc:Literal>
         <xsl:value-of select="normalize-space(/GetRecords/ToDate/text())"/>
       </ogc:Literal>
     </ogc:PropertyIsLessThanOrEqualTo>
   </xsl:if>
 </xsl:template>

  <xsl:attribute-set name="GetRecordsAttributes">
    <xsl:attribute name="version">2.0.2</xsl:attribute>
    <xsl:attribute name="service">CSW</xsl:attribute>
    <xsl:attribute name="resultType">RESULTS</xsl:attribute>
    <xsl:attribute name="startPosition">
      <xsl:value-of select="/GetRecords/StartPosition"/>
    </xsl:attribute>
    <xsl:attribute name="maxRecords">
      <xsl:value-of select="/GetRecords/MaxRecords"/>
    </xsl:attribute>
  </xsl:attribute-set>
</xsl:stylesheet>

When you have finished editing the text, save the file as GetRecords_Request.xslt.

Author the GetRecords_Response.xslt

The geoportal applies a transformation that translates the remote catalog service response for the submitted search criteria into resulting records for access by the geoportal. The code snippet below shows a generic GetRecords_Response.xslt with annotation in the commented sections describing details for important parts of the file. Copy this text into a text editor and make the adjustments described in the comments. Note that where specific metadata elements are referenced in select statements in this example, you need to verify the metadata schema that your remote catalog service uses and that the selected elements comply with that schema. For example, in the element below, the example shows that the dc:identifier element will be selected. This is correct if the catalog service's response is based on Dublin Core. But if your catalog service's response is based on ISO 19139, the element's select statement should be changed to gmd:fileIdentifier/gco:CharacterString instead.

<?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:csw="http://www.opengis.net/cat/csw/2.0.2"
 xmlns:dct="http://purl.org/dc/terms/"
 xmlns:ows="http://www.opengis.net/ows"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 exclude-result-prefixes="csw dc dct ows">
 <xsl:output method="xml" indent="no" encoding="UTF-8" omit-xml-declaration="yes" />
 <xsl:template match="/">
   <xsl:choose>
     <!-- if CSW response returns some exception, do the following -->
     <xsl:when test="/ows:ExceptionReport">
       <exception>
         <exceptionText>
           <xsl:for-each select="/ows:ExceptionReport/ows:Exception">
             <xsl:value-of select="ows:ExceptionText"/>
           </xsl:for-each>
         </exceptionText>
       </exception>
     </xsl:when>
     <xsl:otherwise>
       <Records>
         <xsl:attribute name="maxRecords">
           <xsl:value-of
            select="/csw:GetRecordsResponse/csw:SearchResults/@numberOfRecordsMatched"/>
         </xsl:attribute>
         <xsl:for-each
          select="/csw:GetRecordsResponse/csw:SearchResults/csw:Record |
          /csw:GetRecordsResponse/csw:SearchResults/csw:BriefRecord |
          /csw:GetRecordByIdResponse/csw:Record |
          /csw:GetRecordsResponse/csw:SearchResults/csw:SummaryRecord">
           <Record>
            <ID>
              <xsl:choose>
                <xsl:when
                 test="string-length(normalize-space(dc:identifier[@scheme=
                 'urn:x-esri:specification:ServiceType:ArcIMS:Metadata:DocID']/text())) > 0">
                  <xsl:value-of select="normalize-space(dc:identifier[@scheme=
                   'urn:x-esri:specification:ServiceType:ArcIMS:Metadata:DocID'])"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="normalize-space(dc:identifier)"/>
                </xsl:otherwise>
              </xsl:choose>
            </ID>
            <Title><xsl:value-of select="dc:title"/></Title>
            <Abstract><xsl:value-of select="dct:abstract"/></Abstract>
            <Type><xsl:value-of select="dc:type"/></Type> 
            <!--
              each profile could have a different type of
              bounding box. Some of have two, some have four. This one has four
            -->
            <LowerCorner>
              <xsl:value-of select="ows:WGS84BoundingBox/ows:LowerCorner"/>
            </LowerCorner>
            <UpperCorner>
              <xsl:value-of select="ows:WGS84BoundingBox/ows:UpperCorner"/>
            </UpperCorner>
            <MaxX>
              <xsl:value-of
               select="normalize-space(substring-before(ows:WGS84BoundingBox/ows:UpperCorner, ' '))"/>
            </MaxX>
            <MaxY>
              <xsl:value-of
               select="normalize-space(substring-after(ows:WGS84BoundingBox/ows:UpperCorner, ' '))"/>
            </MaxY>
            <MinX>
              <xsl:value-of
               select="normalize-space(substring-before(ows:WGS84BoundingBox/ows:LowerCorner, ' '))"/>
            </MinX>
            <MinY>
              <xsl:value-of
               select="normalize-space(substring-after(ows:WGS84BoundingBox/ows:LowerCorner, ' '))"/>
            </MinY>
            <ModifiedDate><xsl:value-of select="./dct:modified"/></ModifiedDate>
            <!--
              used to extract any urls in the document. It gets the urls
              and the scheme attribute (@scheme, which determines their type
              (type of url it is (thumbnail, website, server, contact, etc.
              urls)). We always choose the "server" url when we add to map.
            -->
            <References>
              <xsl:for-each select="./dct:references">
                <xsl:value-of select="."/>
                <xsl:text>&#x2714;</xsl:text>
                <xsl:value-of select="@scheme"/>
                <xsl:text>&#x2715;</xsl:text>
              </xsl:for-each>
            </References>
            <!-- 
              this extracts content type information. Can be used to
              highlight add to map button
            -->
            <Types>
              <xsl:for-each select="./dc:type">
                <xsl:value-of select="."/>
                <xsl:text>&#x2714;</xsl:text>
                <xsl:value-of select="@scheme"/>
                <xsl:text>&#x2715;</xsl:text>
              </xsl:for-each>
            </Types>
          </Record>
        </xsl:for-each>
      </Records>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
</xsl:stylesheet>

When you have finished editing the text, save the file as 'GetRecords_Response.xslt'.

Author the GetRecordByID_Response.xslt

The geoportal applies the GetRecordByID_Response.xslt to a GetRecordsByID response from the remote catalog service to provide metadata for a particular record in the remote catalog - this is used for the results on the geoportal search page as well. The code snippet below shows a generic GetRecordsByID_Response.xslt. An especially important part of customizing this is to identify where in the CS-W response information about a live service would be found. This should be defined in the <xsl:template></xsl:template> section with select statements. The example shown below is for a Dublin Core catalog service, and we see that the xpath to the service information can be found at the csw:record/dct:references element. For examples that use ArcIMS CS-W connectors or ISO 19139-based connectors, open other GetRecordByID_Response xslt's within the \\CSWClients\Data folder and look for an example that is similar to the standard that your remote catalog service uses.

<?xml version="1.0" encoding="UTF-8"?> 
 <xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" 
  xmlns:dct="http://purl.org/dc/terms/" 
  xmlns:ows="http://www.opengis.net/ows" 
  exclude-result-prefixes="csw dct">
   <xsl:output method="text" indent="no" encoding="UTF-8"/> 
   <xsl:template match="/"> 
     <xsl:choose>
       <xsl:when test="/ows:ExceptionReport">
         <exception>
           <exceptionText>
             <xsl:for-each select="/ows:ExceptionReport/ows:Exception">
               <xsl:value-of select="ows:ExceptionText"/> 
             </xsl:for-each>
           </exceptionText>
         </exception>
       </xsl:when> 
       <xsl:otherwise>
         <xsl:apply-templates select="//csw:Record/dct:references"/>
       </xsl:otherwise>
     </xsl:choose>
   </xsl:template>
   <xsl:template match="//csw:Record/dct:references"> 
     <xsl:value-of select="."/>
     <xsl:text>&#x2714;</xsl:text>
     <xsl:value-of select="@scheme"/>
     <xsl:text>&#x2715;</xsl:text>
   </xsl:template>
 </xsl:stylesheet>

When you have finished editing the text, save the file as 'GetRecordByID_Response.xslt'.

Add your profile to the CSWProfiles.xml file

After you have authored the three xslt's, you will reference them in the host geoportal's \\geoportal\WEB&#45;INF\classes\gpt\search\profiles\CSWProfiles.xml file.

  • Decide on a prefix that will distinguish your xslt's from the others found in the \\CSWClients\Data directory. Change the names of your three xslt's to include this prefix. For example, GetRecords_Request.xslt becomes MyOrganizationName_GetRecords_Request.xslt.
  • Open the \\geoportal\WEB&#45;INF\classes\gpt\search\profiles\CSWProfiles.xml file in a text editor.
  • Copy the following text into an entry at the top of the file, just below the tag. Update the commented sections to reference the name of your new profile and the three xslt's that you have authored.
<?xml version="1.0" encoding="utf-8" ?> 
<CSWProfiles>
  <!-- insert the name of your profile here within comments -->
  <Profile>
  <!-- 
    update the ID value with a unique urn value. Doesn't matter what it 
    is as long as it is unique within this file -->
    <ID>urn:ogc:CSW:2.0.2:HTTP:YourProfile </ID> 
    <!--
      update the Name value with the name you want to display for your
      profile in the Profile drop-down on the Register network resource page 
      in the geoportal
    -->
    <Name> Unique name for display of Profile </Name>
    <!-- 
      update the CswNamespace value with the namespace for your CSW service. 
      For CSW 2.0.2 services, this will typically be
      http://www.opengis.net/cat/csw/2.0.2. For earlier CSW services, 
      this may be http://www.opengis.net/cat/csw or another namespace
    --> 
    <CswNamespace> http://www.opengis.net/cat/csw/2.0.2 </CswNamespace> 
    <Description />
    <GetRecords> 
      <XSLTransformations>
        <!-- update with the name of your custom profile's GetRecords_Request.xslt file-->
        <Request>MyOrganizationName_GetRecords_Request.xslt</Request>
        <!-- update with the name of your custom profile's GetRecords_Response.xslt file-->
        <Response>MyOrganizationName_GetRecords_Response.xslt</Response>
      </XSLTransformations>
    </GetRecords>
    <GetRecordByID>
      <RequestKVPs>
        <!-- 
          update with syntax appropriate for issuing a GetRecordById request to 
          the type catalog service to which you want to connect. In this example,
          the service would use CS-W 2.0.2 protocol and the full set of metadata 
          record elements from each source record that should be presented in the
         response (ElementSetName) 
       -->
       <![CDATA[service=CSW&request=GetRecordById&version=2.0.2&ElementSetName=full]]>
     </RequestKVPs> 
     <XSLTransformations> 
       <!-- update with the name of your custom profile's GetRecordByID_Response.xslt file-->
       <Response>MyOrganizationName_GetRecordByID_Response.xslt </Response>
     </XSLTransformations>
   </GetRecordByID>
   <!-- update with True if the CS-W service supports returning queries defined by an extent-->
   <SupportSpatialQuery>True </SupportSpatialQuery> 
   <!-- update with True if the CS-W service supports returning the content type of a metadata record--> 
   <SupportContentTypeQuery> True </SupportContentTypeQuery> 
   <!-- update with True if the CS-W service supports returning bounding box information -->
   <SupportSpatialBoundary> True </SupportSpatialBoundary>
 </Profile>
  • Save the CSWProfiles.xml file.

Copy files to the geoportal web application

The geoportal web application will need to be able to access the customized xslt files. Copy them to the \\geoportal\WEB-INF\classes\gpt\search\profiles directory.

Restart and Test

For changes to be applied to your geoportal, you will need to restart the geoportal web application. To test your customization, login to the geoportal and go to the Register a Resource on the Network page. When you select the CSW radio, you should now see the name of your custom CSW profile in the list in the "Profile" field.


Back to How to Publish Resources
Clone this wiki locally