-->

My life was once filled with fancy server-side scripts, but now I'm just another SharePoint consultant.

Showing posts with label XML. Show all posts
Showing posts with label XML. Show all posts

Wednesday, January 14, 2009

Non-programmatic Perl to XML Web Part Kludge

Yes! I love ugly processes! What I'm about to describe can, without a doubt, be handled with 5 lines of .NET code. But, what the heck, let's take the scenic route.

What? An attempt to automate an IT business process.

What process? Determining who is at the quota warning level for a file share.

But... Yes, I know it could be done like that... This is how I did it.


Step 1: Acquire Data

Get a report from the Windows Management Instrumentation (WMI) interface for your file server. I do this from a domain joined machine, logged in as a domain admin. If WMI is not enabled on your server, or if a firewall is blocking this query, I can't help you.

Run this from a command-line:

wmic /node:$fileservername diskquota >> quotas.txt

Replace $fileservername with the appropriate server name, or possibly a full-qualified domain name or DNS name.

Let it crunch. On my file server, I get back about 500 entries across several logical disks. The file that's returned (quotas.txt) is a tab-separated values file, a table if you will, with the following 6 fields:

DiskSpaceUsed, Limit, QuotaVolume, Status, User, WarningLimit


Step 2: Crunch Data with Perl

You'll want to take your quotas.txt file and run it through a Perl script that I tweaked up one day. It's a pretty simple script that imports the data, looks for rows with Status = 1, and creates an XML file.

"Status" maps to the WMI diskquota object model:

Case 0 = "OK"
Case 1 = "Warning limit reached"
Case 2 = "Quota exceeded"

(Stolen from Hey, Scripting Guy!)

The script creates an XML file, with nodes setup as such:

<quota>
<person>rickastley</person>
<percent>81.0</percent>
<remain>152.0</remain>
<limit>800</limit>
</quota>

(Both "remain" and "limit" are in MB)

Step 3: Upload your new data into an XML web part

Create an XML web part on a site page.
Within the XML web part modification tool, there are two editors, one for XML, and one for XSLT.

Open the XML Editor.
Copy and paste all the data from the XML file that Perl created.
Hit Okay.

Open the XSL Editor.
Copy and paste the following code:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
<body>
<table border="1">
<tr bgcolor="#d4cc71">
<th>Account</th>
<th>Percent</th>
<th>Remaining</th>
<th>Quota</th>
</tr>
<xsl:for-each select="danger/quota">
<xsl:sort select="percent" data-type="number"/>
<tr>
<td>
<a><xsl:attribute name="href">http://mysites/Person.aspx?accountname=<xsl:value-of select="person"/></xsl:attribute><xsl:value-of select="person"/></a>
</td>
<td align="right"><xsl:value-of select="percent"/></td>
<td align="right"><xsl:value-of select="remain"/> MB</td>
<td align="right"><xsl:value-of select="limit"/> MB</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

The XSLT formats and tweaks the XML data. It tells the browser to create a table row for each "quota" node and to sort these rows by the "percent" value, which is the percentage of quota used by a specific user.

The XSLT also presents user names as links to their "mysite" pages, specifically the "Person.aspx" view, which does not require a user to have set up their "My Site" site collection. Since the "person" value in the XML maps to the SAM account name of my domain, and because my SharePoint server has an SSP hooked to Active Directory, this works flawlessly.


Step 4: Have fun doing this regularly, since it's not automated

Enough said...

Of course I could automate this kludgy process, but then I'd be missing out on something.

Tuesday, January 13, 2009

Learning XML...

So much of SharePoint is built on XML/XSLT.

It's time I updated my skill set from just a few years ago when I hacked together a "web-scraper" out of Perl. The output file was pure XML with the proper headers to make an RSS feed. The scraper worked for a week, until the regular expressions it looked for changed. Soon the company's RSS feed was being created manually by simply editing the XML file and adding a new node.

With SharePoint, you need not worry about creating properly formatted XML. The application spits out XML as easily as a hobo spits out teeth. The real factor here is what you can do with the XML as presented, and that's where the XSLT comes in. XML is a breeze, but XSLT files take some skill.

The Data Form Web Part contains an <Xsl> tag wherein transforms are done.


What is it transforming? A data source.

Where is the data source defined? In the .NET code, directly above the <Xsl> tag.

What's .NET code? Ask me in 6 months...

You're lying? Like a rug...


Monday, January 12, 2009

Printing List Items

Why someone would need to “Print” from SharePoint is a little confusing. SharePoint is your new logical filing cabinet, fully virtualized with meta-tags. Just like you undoubtedly have dozens of colleagues begging you “not to print this email to help save the environment,” you can bet that some of your business processes still depend on or demand a printed sheet.

But printing from SharePoint, out-of-the-box, is very limited. You’re stuck with either browser printing or the inevitable “screen shot and crop” method of narrowing down content to one, clean page.

I google-found one suitable solution from Ishai Sagi to print out lists: http://www.sharepoint-tips.com/2007/01/how-to-add-print-list-option-to-list.html

After some more googling I found a decent solution from Vincent Rothwell: http://blog.thekid.me.uk/archive/2007/07/22/easily-print-sharepoint-lists-using-your-own-template.aspx

I went ahead and installed Rothwell's solution on a SharePoint team site that I knew people would want to get print-outs from. It was an out-of-the-box "Call Center" site template to track trouble tickets for our help desk operation. The solution contains javascript, images and XSLT files to manage the display of XML-based list data to the print engine.

It's an impressive solution, and I was able to extend the functionality with a few tricks.

First off, it will print an itemized list based on the fields displayed in your list view. This required me to create new list views just for printing. Some views had too many columns, others did not have enough. In our usage, we will be printing out individual items much more than a filtered list of items. The "item" print function gets its fields from the display view as well, so, for really extending the single item print process, I had to create a a list view showing all the fields available.

Rothwell's item print layout basically spits out an HTML table with ugly field names and field values that needed to be cleaned up. For instance, many field values were be returned with "nn;#" at the beginning. Values with this prefixed garbage needed to transformed with an XSLT, aka an XML Style-Sheet Transform. Here's an example, hacked from Rothwell's "common.xsl" file:

<xsl:template match="@*[name() = 'ows_Author' or name() = 'ows_Editor' ]">
<xsl:value-of select="substring-after(., ';#')" />
</xsl:template>


What it's saying is, "Hey, if you find these fields, and you property refer them to this template, spit out the value after the ',#' garbage..." It worked like a charm.

(By the way, the ows_Author is the "Created By" field and ows_Editor is the "Modified By" field)

I struggled for a bit trying to massage the field values by editing the "common.xsl" file, which is a shared file that handles the data templates for matching field names. I couldn't seem to definitively come up with a precise field list, both in terms of field names and fields that I could display. I installed Fiddler to check out the XML data presented in a list view. From Fiddler I was able to determine field names from the "z:row" XML data.

The "Call Center" service request data type contains a field called "Comments" that gets appended to each time you save an item. SharePoint displays this data as it should. Each comment has a time stamp and a user name and is presented as it should be over the WWW. The field type was "Multiple Line" with the "Append Changes to Existing Text" bit turned on.

I wanted all the comments on my item print sheet, but SharePoint was uncooperative. The XML data it spit out for that field returned only the last comment without a proper time stamp or user associated with the comment. Since the print out data is based on list view data, I changed one of my "view" aspx pages, which was just an XML markup web part to an XSLT data view web part.

I was able to get the list view data from the Comments field to show all appended changes, but I wasn't able to manipulate this data via my item print XSLT.

I might get there someday... Or I may just accept defeat.



About Me

My photo
Chicago, Illinois, United States