An easy and cheap way to build a stock quote web part is to use the Data View Web Part and the apparently free Stock Quote Web Service from WebServiceX.Net [Update 6/29/2018: the stock quote service is no longer there].
I built one today in less than 75 minutes, and much of that was spent figuring out how I could use the substring-before and substring-after commands to parse the XML blob returned by the service. Now you can do it in 5 minutes.
Once I built this web part, I exported it to a .webpart file. A .webpart file is just an XML file, which means that if all you need is a stock quote for a single stock, you can just reuse this web part and you don’t even need to go back into SharePoint Designer to change the ticker symbol.
So this is what you do:
- Take the content below and save it to a text file. You can either copy and paste below, or right click this link and “Save Target As…”
- Replace the MSFT ticker symbol with the symbol of your choice. See where I have highlighted it below.
- Rename the file to end in .webpart.
- Add (import) the web part to a web part zone on a web part page in a SharePoint site. When you are done, it should look like this [Update 6/29/2018: It showed a stock quote for MSFT. It no longer works as the underlying stock quote webservice went away.]
If you need a refresher on using the Data View Web Part, Dustin Miller has an excellent webcast [Update 6/29/2018: Gone] on this topic.
If for some reason, this stock quote web part doesn’t meet your requirements, Data Springs makes some [Update 6/29/2018: Not any more. They are now at http://www.datasprings.com/ and only make DNN modules].
This is provided as-is, no warranties implied, etc. etc.
<webParts>
<webPart xmlns=”http://schemas.microsoft.com/WebPart/v3″>
<metaData>
<type name=”Microsoft.SharePoint.WebPartPages.DataFormWebPart, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” />
<importErrorMessage>Cannot import this Web Part.</importErrorMessage>
</metaData>
<data>
<properties>
<property name=”MissingAssembly” type=”string”>Cannot import this Web Part.</property>
<property name=”FireInitialRow” type=”bool”>True</property>
<property name=”TitleIconImageUrl” type=”string” />
<property name=”HelpMode” type=”helpmode”>Modeless</property>
<property name=”CacheXslStorage” type=”bool”>True</property>
<property name=”ViewContentTypeId” type=”string” />
<property name=”Description” type=”string” />
<property name=”DataSourcesString” type=”string”><%@ Register TagPrefix=”sharepoint” Namespace=”Microsoft.SharePoint.WebControls” Assembly=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %><sharepoint:SoapDataSource runat=”server” SelectUrl=”http://www.webservicex.net/stockquote.asmx” InsertUrl=”” UpdateUrl=”” DeleteUrl=”” SelectAction=”http://www.webserviceX.NET/GetQuote” InsertAction=”” UpdateAction=”” DeleteAction=”” SelectPort=”StockQuoteSoap” InsertPort=”” UpdatePort=”” DeletePort=”” SelectServiceName=”StockQuote” InsertServiceName=”” UpdateServiceName=”” DeleteServiceName=”” AuthType=”None” WsdlPath=”http://www.webservicex.net/stockquote.asmx?WSDL” XPath=”” ID=”SoapDataSource4″><SelectCommand>
<soap:Envelope xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”><soap:Body><GetQuote xmlns=”http://www.webserviceX.NET/”><symbol>MSFT</symbol></GetQuote></soap:Body></soap:Envelope></SelectCommand>
<InsertCommand>
</InsertCommand>
<UpdateCommand>
</UpdateCommand>
<DeleteCommand>
</DeleteCommand>
</sharepoint:SoapDataSource>
</property>
<property name=”AllowZoneChange” type=”bool”>True</property>
<property name=”ParameterBindings” type=”string”>
<ParameterBinding Name=”dvt_apos” Location=”Postback;Connection”/>
<ParameterBinding Name=”UserID” Location=”CAMLVariable” DefaultValue=”CurrentUserName”/>
<ParameterBinding Name=”Today” Location=”CAMLVariable” DefaultValue=”CurrentDate”/>
<ParameterBinding Name=”dvt_firstrow” Location=”Postback;Connection”/>
<ParameterBinding Name=”dvt_nextpagedata” Location=”Postback;Connection”/>
</property>
<property name=”PageSize” type=”int”>1</property>
<property name=”TitleUrl” type=”string” />
<property name=”ViewFlag” type=”string”>0</property>
<property name=”Xsl” type=”string”>
<xsl:stylesheet xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:ddw1=”http://www.webserviceX.NET/” version=”1.0″ exclude-result-prefixes=”xsl msxsl ddwrt” xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime” xmlns:asp=”http://schemas.microsoft.com/ASPNET/20″ xmlns:__designer=”http://schemas.microsoft.com/WebParts/v2/DataView/designer” xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:msxsl=”urn:schemas-microsoft-com:xslt” xmlns:SharePoint=”Microsoft.SharePoint.WebControls” xmlns:ddwrt2=”urn:frontpage:internal”>
<xsl:output method=”html” indent=”no”/>
<xsl:decimal-format NaN=””/>
<xsl:param name=”dvt_apos”>&apos;</xsl:param>
<xsl:param name=”dvt_firstrow”>1</xsl:param>
<xsl:param name=”dvt_nextpagedata” />
<xsl:variable name=”dvt_1_automode”>0</xsl:variable>
<xsl:template match=”/” xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/” xmlns:ddw1=”http://www.webserviceX.NET/” xmlns:asp=”http://schemas.microsoft.com/ASPNET/20″ xmlns:__designer=”http://schemas.microsoft.com/WebParts/v2/DataView/designer” xmlns:SharePoint=”Microsoft.SharePoint.WebControls”>
<xsl:call-template name=”dvt_1″/>
</xsl:template>
<xsl:template name=”dvt_1″>
<xsl:variable name=”dvt_StyleName”>RepForm3</xsl:variable>
<xsl:variable name=”Rows” select=”/soap:Envelope/soap:Body/ddw1:GetQuoteResponse”/>
<xsl:variable name=”dvt_RowCount” select=”count($Rows)” />
<xsl:variable name=”RowLimit” select=”1″ />
<xsl:variable name=”FirstRow” select=”$dvt_firstrow” />
<xsl:variable name=”LastRow”>
<xsl:choose>
<xsl:when test=”($FirstRow + $RowLimit – 1) &gt; $dvt_RowCount”><xsl:value-of select=”$dvt_RowCount” /></xsl:when>
<xsl:otherwise><xsl:value-of select=”$FirstRow + $RowLimit – 1″ /></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name=”IsEmpty” select=”$dvt_RowCount = 0″ />
<table border=”0″ width=”100%”>
<xsl:call-template name=”dvt_1.body”>
<xsl:with-param name=”Rows” select=”$Rows[position() &gt;= $FirstRow and position() &lt;= $LastRow]”/>
<xsl:with-param name=”FirstRow” select=”1″ />
<xsl:with-param name=”LastRow” select=”$dvt_RowCount” />
</xsl:call-template>
</table>
<xsl:call-template name=”dvt_1.commandfooter”>
<xsl:with-param name=”FirstRow” select=”$FirstRow” />
<xsl:with-param name=”LastRow” select=”$LastRow” />
<xsl:with-param name=”RowLimit” select=”$RowLimit” />
<xsl:with-param name=”dvt_RowCount” select=”$dvt_RowCount” />
<xsl:with-param name=”RealLastRow” select=”number(ddwrt:NameChanged(”,-100))” />
</xsl:call-template>
</xsl:template>
<xsl:template name=”dvt_1.body”>
<xsl:param name=”Rows”/>
<xsl:param name=”FirstRow” />
<xsl:param name=”LastRow” />
<xsl:for-each select=”$Rows”>
<xsl:variable name=”dvt_KeepItemsTogether” select=”false()” />
<xsl:variable name=”dvt_HideGroupDetail” select=”false()” />
<xsl:if test=”(position() &gt;= $FirstRow and position() &lt;= $LastRow) or $dvt_KeepItemsTogether”>
<xsl:if test=”not($dvt_HideGroupDetail)” ddwrt:cf_ignore=”1″>
<xsl:call-template name=”dvt_1.rowview” />
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name=”dvt_1.rowview”>
<tr>
<td><xsl:value-of select=”concat(substring-before(substring-after(ddw1:GetQuoteResult,’&lt;Name&gt;’),’&lt;/Name&gt;’),’ (‘,substring-before(substring-after(ddw1:GetQuoteResult,’&lt;Symbol&gt;’),’&lt;/Symbol&gt;’),’)’)” /></td>
</tr><tr><td><table border=”0″ cellspacing=”0″ width=”100%”><tr><td class=”ms-vb” style=”width: 60%”><xsl:text xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime” ddwrt:nbsp-preserve=”yes” disable-output-escaping=”yes”>&amp;nbsp;</xsl:text>
<strong>As Of:</strong></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”concat(
substring-before(substring-after(ddw1:GetQuoteResult,’&lt;Time&gt;’),’&lt;/Time&gt;’),’ ‘,
substring-before(substring-after(ddw1:GetQuoteResult,’&lt;Date&gt;’),’&lt;/Date&gt;’))” /></td></tr><tr class=”ms-searchimage”><td class=”ms-vb” style=”width: 60%”><strong>Last:</strong></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;Last&gt;’),’&lt;/Last&gt;’)” /></td></tr><tr><td class=”ms-vb” style=”width: 60%”><strong>Change:
<xsl:text xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime” ddwrt:nbsp-preserve=”yes” disable-output-escaping=”yes”>&amp;nbsp;</xsl:text>
</strong></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;Change&gt;’),’&lt;/Change&gt;’)” /></td></tr><tr class=”ms-searchimage”><td class=”ms-vb” style=”width: 60%”><strong>Open:</strong></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;Open&gt;’),’&lt;/Open&gt;’)” /></td></tr><tr><td class=”ms-vb” style=”width: 60%”><strong>Low:</strong></td><td width=”75%” class=”ms-vb”><span><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;Low&gt;’),’&lt;/Low&gt;’)” /></span></td></tr>
<xsl:if test=”$dvt_1_automode = ‘1’” ddwrt:cf_ignore=”1″>
<tr>
<td colspan=”99″ class=”ms-vb”>
<span ddwrt:amkeyfield=”” ddwrt:amkeyvalue=”string($XPath)” ddwrt:ammode=”view”></span>
</td>
</tr></xsl:if>
<tr class=”ms-searchimage”><td class=”ms-vb” style=”width: 60%”><strong>High
<xsl:text xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime” ddwrt:nbsp-preserve=”yes” disable-output-escaping=”yes”>&amp;nbsp;</xsl:text>
</strong></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;High&gt;’),’&lt;/High&gt;’)” /></td></tr>
<tr><td class=”ms-vb” style=”width: 60%”><strong>Volume:
<xsl:text xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime” ddwrt:nbsp-preserve=”yes” disable-output-escaping=”yes”>&amp;nbsp;</xsl:text></strong></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;Volume&gt;’),’&lt;/Volume&gt;’)” /></td></tr>
<tr class=”ms-searchimage”><td class=”ms-vb” style=”width: 60%”><strong>Market Cap:
<xsl:text xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime” ddwrt:nbsp-preserve=”yes” disable-output-escaping=”yes”>&amp;nbsp;
</xsl:text></strong></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;MktCap&gt;’),’&lt;/MktCap&gt;’)” /></td></tr>
<tr><td class=”ms-vb” style=”width: 60%”><strong>Previous Close:</strong>
<xsl:text xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime” ddwrt:nbsp-preserve=”yes” disable-output-escaping=”yes”>&amp;nbsp;
</xsl:text></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;PreviousClose&gt;’),’&lt;/PreviousClose&gt;’)” /></td></tr>
<tr class=”ms-searchimage”><td class=”ms-vb” style=”width: 60%”><strong>Percentage Change:</strong>
<xsl:text xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime” ddwrt:nbsp-preserve=”yes” disable-output-escaping=”yes”>&amp;nbsp;
</xsl:text></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;PercentageChange&gt;’),’&lt;/PercentageChange&gt;’)” /></td></tr>
<tr><td class=”ms-vb” style=”width: 60%”><strong>12 Month Range:</strong></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;AnnRange&gt;’),’&lt;/AnnRange&gt;’)” /></td></tr>
<tr class=”ms-searchimage”><td class=”ms-vb” style=”width: 60%”><strong>Earnings Per Share:</strong>
<xsl:text xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime” ddwrt:nbsp-preserve=”yes” disable-output-escaping=”yes”>&amp;nbsp;
</xsl:text></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;Earns&gt;’),’&lt;/Earns&gt;’)” /></td></tr>
<tr><td class=”ms-vb” style=”width: 60%”><strong>P-E:
<xsl:text xmlns:ddwrt=”http://schemas.microsoft.com/WebParts/v2/DataView/runtime” ddwrt:nbsp-preserve=”yes” disable-output-escaping=”yes”>&amp;nbsp;</xsl:text></strong></td><td width=”75%” class=”ms-vb”><xsl:value-of select=”substring-before(substring-after(ddw1:GetQuoteResult,’&lt;P-E&gt;’),’&lt;/P-E&gt;’)” /></td></tr>
</table></td></tr></xsl:template>
<xsl:template name=”dvt_1.commandfooter”>
<xsl:param name=”FirstRow” />
<xsl:param name=”LastRow” />
<xsl:param name=”RowLimit” />
<xsl:param name=”dvt_RowCount” />
<xsl:param name=”RealLastRow” />
<table cellspacing=”0″ cellpadding=”4″ border=”0″ width=”100%”>
<tr>
<xsl:if test=”$FirstRow &gt; 1 or $LastRow &lt; $dvt_RowCount”>
<xsl:call-template name=”dvt_1.navigation”>
<xsl:with-param name=”FirstRow” select=”$FirstRow” />
<xsl:with-param name=”LastRow” select=”$LastRow” />
<xsl:with-param name=”RowLimit” select=”$RowLimit” />
<xsl:with-param name=”dvt_RowCount” select=”$dvt_RowCount” />
<xsl:with-param name=”RealLastRow” select=”$RealLastRow” />
</xsl:call-template>
</xsl:if>
</tr>
</table>
</xsl:template>
<xsl:template name=”dvt_1.navigation”>
<xsl:param name=”FirstRow” />
<xsl:param name=”LastRow” />
<xsl:param name=”RowLimit” />
<xsl:param name=”dvt_RowCount” />
<xsl:param name=”RealLastRow” />
<xsl:variable name=”PrevRow”>
<xsl:choose>
<xsl:when test=”$FirstRow – $RowLimit &lt; 1″>1</xsl:when>
<xsl:otherwise>
<xsl:value-of select=”$FirstRow – $RowLimit” />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name=”LastRowValue”>
<xsl:choose>
<xsl:when test=”$LastRow &gt; $RealLastRow”>
<xsl:value-of select=”$LastRow”></xsl:value-of>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select=”$RealLastRow”></xsl:value-of>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name=”NextRow”>
<xsl:value-of select=”$LastRowValue + 1″></xsl:value-of>
</xsl:variable>
<td nowrap=”nowrap” class=”ms-paging” align=”right”>
<xsl:if test=”$dvt_firstrow &gt; 1″ ddwrt:cf_ignore=”1″>
<a>
<xsl:attribute name=”href”>javascript: <xsl:value-of select=”ddwrt:GenFireServerEvent(‘dvt_firstrow={1}’)” />;</xsl:attribute>
Start</a>
<xsl:text disable-output-escaping=”yes” ddwrt:nbsp-preserve=”yes”>&amp;nbsp;</xsl:text>
<a>
<xsl:attribute name=”href”>javascript: <xsl:value-of select=”ddwrt:GenFireServerEvent(concat(‘dvt_firstrow={‘,$PrevRow,’}’))” />;</xsl:attribute>
<img src=”/_layouts/images/prev.gif” border=”0″ alt=”Previous” />
</a>
<xsl:text disable-output-escaping=”yes” ddwrt:nbsp-preserve=”yes”>&amp;nbsp;</xsl:text>
</xsl:if>
<xsl:value-of select=”$FirstRow” />
– <xsl:value-of select=”$LastRowValue” />
<xsl:text disable-output-escaping=”yes” ddwrt:nbsp-preserve=”yes”>&amp;nbsp;</xsl:text>
<xsl:if test=”$LastRowValue &lt; $dvt_RowCount or string-length($dvt_nextpagedata)!=0″ ddwrt:cf_ignore=”1″>
<a>
<xsl:attribute name=”href”>javascript: <xsl:value-of select=”ddwrt:GenFireServerEvent(concat(‘dvt_firstrow={‘,$NextRow,’}’))” />;</xsl:attribute>
<img src=”/_layouts/images/next.gif” border=”0″ alt=”Next” />
</a>
</xsl:if>
</td>
</xsl:template>
</xsl:stylesheet> </property>
<property name=”NoDefaultStyle” type=”string”>TRUE</property>
<property name=”Direction” type=”direction”>NotSet</property>
<property name=”UseSQLDataSourcePaging” type=”bool”>True</property>
<property name=”ListName” type=”string” null=”true” />
<property name=”Hidden” type=”bool”>False</property>
<property name=”DisplayName” type=”string” />
<property name=”SampleData” type=”string” null=”true” />
<property name=”HelpUrl” type=”string” />
<property name=”ChromeType” type=”chrometype”>BorderOnly</property>
<property name=”CatalogIconImageUrl” type=”string” />
<property name=”Height” type=”string” />
<property name=”DataFields” type=”string”>ddw1:GetQuoteResult,GetQuoteResult;</property>
<property name=”Default” type=”string” />
<property name=”ChromeState” type=”chromestate”>Normal</property>
<property name=”DataSourceID” type=”string” />
<property name=”AllowClose” type=”bool”>True</property>
<property name=”CacheXslTimeOut” type=”int”>86400</property>
<property name=”AllowMinimize” type=”bool”>True</property>
<property name=”AllowEdit” type=”bool”>True</property>
<property name=”XslLink” type=”string” null=”true” />
<property name=”Title” type=”string”>Stock Ticker</property>
<property name=”Width” type=”string” />
<property name=”ShowWithSampleData” type=”bool”>False</property>
<property name=”ExportMode” type=”exportmode”>All</property>
<property name=”AllowHide” type=”bool”>True</property>
<property name=”AllowConnect” type=”bool”>True</property>
</properties>
</data>
</webPart>
</webParts>
–Michael