mandag den 17. oktober 2011

SharePoint 2010 and How to Build XML and Display ListItem with XSLT

SharePoint Apps



In the following, I'll explain how to build XML on-the-fly and display data with XSLT. The advantage of this approach is that you always can edit the way data is displayed without changing the code in C# and deploying the new assembly.

So, if you are tired of using StringBuilder to display data in your web parts, check out the description below:

I assume that you know how to create a web part in VisualStudio and write the code to fetch SPListItem that I defined as "projectitem" in the code.

SPListItem projectitem=.....

You can define the path to XSLT file as a web part property that is editable in the web part ToolPane:

private string _xslt = "/Style Library/Projects/ProjectInfo.xsl";

[WebBrowsable(true),
Category("ProjectInfo settings"),
DefaultValue("Current"),
Personalizable(PersonalizationScope.Shared),
WebDisplayName("XSLT path"),
WebDescription("Pat to XSL file")]
public string XSLT
{
get { return _xslt; }
set { _xslt = value; }
}

Also, define the string that will contain the XML, built on the fly:

string xmlInfo = "";

The code is used to fetch the item from a "Project list" that contains metadata about projects. Whilst I also defined the list of ProjectFields as:

This list is used in the code to save all the list item values - the values, defined in the list item columns.
The code loops through the list item fields (columns), so I also defined the field name and field value as FieldName and FieldValue:


class ProjectFields { public string FieldName { get; set; } public string FieldValue { get; set; } }

I loop through the list item fields (columns):

foreach (SPField field in projectitem.Fields){}

Than, I fetch the value for each field (column). The code to fetch the field value is different for each field type, so

I write something like this:

if (field.Type == SPFieldType.Text){}

or

if (field.TypeAsString == "TaxonomyFieldType"){}

or

if (field.Type == SPFieldType.User){}

Don't forget to check for fields and empty field values:
if (projectitem[field.Title]!=null){}

and

if (projectitem[field.Title].ToString() != ""){}

At the end of the loop, the field name and field value are saved in the list:

projectList.Add(new ProjectFields { FieldName = field.Title.Replace(" ", "_"), FieldValue = itemvalue });

Than, the foreach loop is closed and I can build the XML on the fly:

XElement xml = new XElement("Project");
foreach (ProjectFields data in projectList)
{
xml.Add(new XAttribute(data.FieldName, data.FieldValue));

}

Than, save the XML to a string:
xmlInfo = xml.ToString();

Finally, render the XML with XSL:
protected override void RenderContents(HtmlTextWriter output)
{
RenderChildren(output);
try
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
if (xmlInfo.ToString() != "")
{
string rootWebUrl = SPContext.Current.Site.RootWeb.Url.ToString();

XslCompiledTransform xslt = new XslCompiledTransform();
XmlDocument loadXsl = new XmlDocument();
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

XsltSettings xslt_settings = new XsltSettings();
xslt_settings.EnableScript = true;
xslt.Load(rootWebUrl + XSLT, xslt_settings, resolver);


XmlReader xreader = XmlReader.Create(new System.IO.StringReader(xmlInfo.ToString()));
System.Xml.XPath.XPathDocument pData = new System.Xml.XPath.XPathDocument(xreader);

xslt.Transform(pData, null, output);

}
});
} .......end with catch....


In VisualStudio, add a new module to your project - I called it XSLT and changed the Elements.xml file so it looks like this:

Than, add a new XSL file and call it ProjectInfo.xsl. Here is an example of how to display a field value called

ProjectManager in .xsl file:





NOTICE: DELETE ALL THE br TAGS FROM THE CODE