• [转]MOSS 2007 search customization


    Every time i've been using MOSS 2007 search, i always wanted to have a very simple thing. Before going deeper into the explanations, let's look to the typical item returned after doing the search.

    What we see here?
    Actually we see almost everything that MOSS 2007 search could return OOB (out of the box).
    If you are interested for the details, see Microsoft.Search Schema Reference for Enterprise Search. Also it is worth to check the article Creating and Exposing Managed Properties in the Advanced Search Page of SharePoint Server Enterprise Search.

    But what is the problem?

    The problem is that very often it is nice not only to click on the URL and get the item opened in the corresponding desktop application, but also be able to navigate to the place, where this item is stored. For example, you've been so impressed by my presentation about Groove that you've decided to go to the document library where it is stored and check for something more.. :)
    Again, OOB you would have to:

    • click on the link
    • copy the url to the document
    • paster it to the IE address bar
    • manually delete document name and leave only the path to the document library

    Not so easy, yes?
    Thanks to our MS developers you have an ability to change this.
    In order to do this you have to modify the XSLT rendering script used for search results output.
    The form in which MOSS outputs the results to XML is the following:

    <?xml version="1.0" encoding="utf-8"?>
    <?xml-stylesheet type="text/xsl" href="url-strip-final.xslt"?>
    <All_Results>
     <Result>   
      <workid>1</workid>   
      <rank>222</rank>   
      <title>Title of document or web page</title>   
      <author>Author of document or web page</author>   
      <size>1025</size>   
      <sitename>http://www.sample.com</sitename>   
      <url>http://www.sample.com/folder/document.aspx</url>   
      <imageurl>/_layouts/images/aspx16.gif</imageurl>   
      <description>This is the summary of the document or web page. The summary is generated from the original document based on matches with query terms. In some cases, the summary is a description provided by the author.</description>   
      <write>December 26, 2004</write> 
     </Result>
     <Result>   
      <workid>1</workid>   
      <rank>222</rank>   
      <title>Title of document or web page</title>   
      <author>Author of document or web page</author>   
      <size>1025</size>   
      <sitename>http://www.sample.com</sitename>   
      <url>http://www.sample.com</url>   
      <imageurl>/_layouts/images/aspx16.gif</imageurl>   
      <description>This is the summary of the document or web page. The summary is generated from the original document based on matches with query terms. In some cases, the summary is a description provided by the author.</description>   
      <write>December 26, 2004</write> 
     </Result>
     <Result>   
      <workid>1</workid>   
      <rank>222</rank>   
      <title>Title of document or web page</title>   
      <author>Author of document or web page</author>   
      <size>1025</size>   
      <sitename>http://www.sample.com</sitename>   
      <url>http://www.sample.com/sites/test</url>   
      <imageurl>/_layouts/images/aspx16.gif</imageurl>   
      <description>This is the summary of the document or web page. The summary is generated from the original document based on matches with query terms. In some cases, the summary is a description provided by the author.</description>   
      <write>December 26, 2004</write> 
     </Result>
     <Result>   
      <workid>1</workid>   
      <rank>222</rank>   
      <title>Title of document or web page</title>   
      <author>Author of document or web page</author>   
      <size>1025</size>   
      <sitename>http://www.sample.com</sitename>   
      <url>http://test/Docs/pics/Forms/DispForm.aspx?ID=2&amp;RootFolder=/Docs/pics</url>   
      <imageurl>/_layouts/images/aspx16.gif</imageurl>   
      <description>This is the summary of the document or web page. The summary is generated from the original document based on matches with query terms. In some cases, the summary is a description provided by the author.</description>   
      <write>December 26, 2004</write> 
     </Result></All_Results>

    You can get nearly the same XML from Search Results web-part toolpane. The thing that i've added here is some special conditions which has to be handled.
    The first one is the situation, when you receive in the results link to the site, which is the root for site collection. In the XML decribed above it is http://www.sample.com/sites/test.

    If we would like to get to it's parent, it would be http://www.sample.com/ and not http://www.sample.com/sites.

    Anyway, to stay with XSLT and not use anything else, you could write the following type of XSLT script to get the desired result.

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:template match="/">
     <xsl:apply-templates />
    </xsl:template>

    <!-- mail processing template, is applied to the each resulting item -->
    <xsl:template match="Result">
     <!-- getting the url to the item, returned from search -->
     <xsl:variable name="result-url" select="url"/>

     <xsl:variable name="res1">
           <xsl:choose>
      <!--for now i have now idea how to deal with urls with ? chars, so we would skip them -->
      <xsl:when test="contains( $result-url, '?' )">
       <xsl:value-of select="$result-url"/>
      </xsl:when>
      <!--for urls that are not referring the root of the web applications, we perform the processing -->
      <xsl:when test="contains( substring-after( $result-url,'http://') ,'/')">
       <xsl:call-template name="mcs-strip-filename">
        <xsl:with-param name="x" select="$result-url"/>
       </xsl:call-template>
      </xsl:when>
      <!-- for all other conditions we do nothing -->
      <xsl:otherwise>
       <xsl:value-of select="$result-url"/>
      </xsl:otherwise>
         </xsl:choose>
     </xsl:variable>
     <!-- postprocessing-->
     <xsl:variable name="res2">
     <xsl:choose>
      <!-- if search returned is the item like
    http://test we would leave it untouched -->
      <xsl:when test="$result-url=$res1">
       <xsl:value-of select="$res1"/>
      </xsl:when>
      <!-- if search returned us the result like
    http://test/sites/site, than the parent should be http://test and not http://test/sites -->
      <xsl:when test="substring-after($result-url,'sites/')=$res1">
       <xsl:value-of select="substring-before($result-url,concat('/sites/',$res1))"/>
      </xsl:when>
      <!-- in all other situations we just strip the doc name from the end and return the result -->
      <xsl:otherwise>
       <xsl:value-of select="substring-before($result-url,$res1)"/>
      </xsl:otherwise>
     </xsl:choose>
     </xsl:variable>
     original-url=<xsl:value-of select="$result-url"/><br/>
     <a href="{$res1}">doc-<xsl:value-of select="$res1"/></a><br/>
     <a href="{$res2}">parent-<xsl:value-of select="$res2"/></a><br/>
     <br/> 
    </xsl:template>

     <xsl:template name="mcs-strip-filename">
       <xsl:param name="x"/>
       <xsl:choose>
         <xsl:when test="contains($x,'/')">
           <xsl:call-template name="mcs-strip-filename">
             <xsl:with-param name="x" select="substring-after($x,'/')"/>
           </xsl:call-template>
         </xsl:when>
         <xsl:otherwise>
           <xsl:value-of select="$x"/>
         </xsl:otherwise>
       </xsl:choose>
     </xsl:template>

    </xsl:stylesheet>

    (note* - it was more than 2 years ago when i've did something using XSLT, so excuse me if you think it could be writtent better or has some errors). 
    This XSLT does few simple things and the main one is that it gives you an ability to get the link to the container for the item.
    .xml and .xslt files described above have been made to demonstrate the possiblity to achieve the results.

    Now let's try to make MOSS 2007 use this. To do this you should open the XSLT editor for Search Results web-part and edit the OOB XSLT. To make it simple search for the string that looks like

         <xsl:call-template name="DisplaySize">
          <xsl:with-param name="size" select="size" />
         </xsl:call-template>
        

    and add just before it the following strings:

         <xsl:call-template name="mcs-get-parent">
          <xsl:with-param name="result-url" select="url" />
         </xsl:call-template>   
     

    After that go to the end of xslt and just before the </xsl:stylesheet> node add the following code

    <xsl:template name="mcs-get-parent">
     <!-- getting the url to the item, returned from search -->
     <xsl:param name="result-url"/>

     <xsl:variable name="res1">
           <xsl:choose>
      <!--for now i have now idea how to deal with urls with ? chars, so we would skip them -->
      <xsl:when test="contains( $result-url, '?' )">
       <xsl:value-of select="$result-url"/>
      </xsl:when>
      <!--for urls that are not referring the root of the web applications, we perform the processing -->
      <xsl:when test="contains( substring-after( $result-url,'http://') ,'/')">
       <xsl:call-template name="mcs-strip-filename">
        <xsl:with-param name="x" select="$result-url"/>
       </xsl:call-template>
      </xsl:when>
      <!-- for all other conditions we do nothing -->
      <xsl:otherwise>
       <xsl:value-of select="$result-url"/>
      </xsl:otherwise>
         </xsl:choose>
     </xsl:variable>
     <!-- postprocessing-->
     <xsl:variable name="res2">
     <xsl:choose>
      <!-- if search returned is the item like
    http://test we would leave it untouched -->
      <xsl:when test="$result-url=$res1">
       <xsl:value-of select="$res1"/>
      </xsl:when>
      <!-- if search returned us the result like
    http://test/sites/site, than the parent should be http://test and not http://test/sites -->
      <xsl:when test="substring-after($result-url,'sites/')=$res1">
       <xsl:value-of select="substring-before($result-url,concat('/sites/',$res1))"/>
      </xsl:when>
      <!-- in all other situations we just strip the doc name from the end and return the result -->
      <xsl:otherwise>
       <xsl:value-of select="substring-before($result-url,$res1)"/>
      </xsl:otherwise>
     </xsl:choose>
     </xsl:variable>
     <span class="srch-URL"><xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text><a href="{$res2}">navigate to parent</a></span>
    </xsl:template>


     <xsl:template name="mcs-strip-filename">
       <xsl:param name="x"/>
       <xsl:choose>
         <xsl:when test="contains($x,'/')">
           <xsl:call-template name="mcs-strip-filename">
             <xsl:with-param name="x" select="substring-after($x,'/')"/>
           </xsl:call-template>
         </xsl:when>
         <xsl:otherwise>
           <xsl:value-of select="$x"/>
         </xsl:otherwise>
       </xsl:choose>
     </xsl:template>


    After applying the changes you would be able to see those type of changes in the result:

    I hope it would be usefull for you and help to get the maximum from MOSS 2007.

    原文地址:http://blogs.technet.com/b/pavelka/archive/2007/05/24/moss-2007-search-customization.aspx

  • 相关阅读:
    java学习笔记(4)多态
    scala学习笔记(1)
    java复习(3)继承下
    java复习(3)继承
    java复习(2)
    java中常见的异常种类
    数组的内存结构
    Castle ActiveRecord学习(一)简介
    OAuth2.0 Owin 授权问题
    将对象转为json,加入到HttpResponseMessage中
  • 原文地址:https://www.cnblogs.com/bmib/p/2003206.html
Copyright © 2020-2023  润新知