Monday, January 11, 2010

Using XPath to manage data returned by a SharePoint Web Service

Topic:

Using XPath to navigate through elements and attributes in an XML document returned  by a SharePoint Web Service. 
This article proposes some examples which will show to developers how to use XPath in spite of namespaces present in the XML returned by Web services of SharePoint

1 - Business benefits (the "why" part of the post)

SharePoint provides Web Services that can be consumed in order for example to get data from a SharePoint Site, and display them within another web site or a desktop application.
It is a part of what is commonly called "SOA" in companies.
On the other hand, this principle can be applied to retrieve data from SharePoint Internet facing web site so as they can be a part of a mashup in a web site.

2- Development benefits

XPath allows developers to quickly navigate through elements and attributes in an XML document. It is very useful when there is no namespaces in the parsed XML, but it becomes more difficult when namespaces are used in the XML, especially if there is several namespaces and that they are present at different locations within the XML code.

2- Common examples

To give common examples, we are going to use the Lists Web Service and two of its methods.
This is a short Microsoft documentation excerpt and a link to it:

Lists Web Service
The Lists Web service provides methods for working with SharePoint lists, content types, list items, and files.
To access this Web service set a Web reference to

http://<site>/_vti_bin/Lists.asmx

 - The GetListCollection Method returns the names and GUIDs for all lists in a specific web site, and the complete SOAP XML returned by the web service looks like this one:

Request result for SharePoint Web Service /_vti_bin/Lists.asmx GetList

<?xml version='1.0' encoding='utf-8'?>

<soap:Envelope

    xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'

    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'

    xmlns:xsd='http://www.w3.org/2001/XMLSchema'>

  <soap:Body>

    <GetListCollectionResponse xmlns='http://schemas.microsoft.com/sharepoint/soap/'>

      <GetListCollectionResult>

        <Lists>

          <List DocTemplateUrl='' DefaultViewUrl='/product/Lists/Demos/AllItems.aspx' MobileDefaultViewUrl='' ID='{91465226-671A-42EC-98ED-52C8C13403A1}' Title='D…

          <List DocTemplateUrl='/product/Documents/Forms/template.doc' DefaultViewUrl='/product/Documents/Forms/AllItems.aspx' MobileDefaultViewUrl='' ID='{3A9CB2…

          <List DocTemplateUrl='' DefaultViewUrl='/product/PublishingImages/Forms/AllItems.aspx' MobileDefaultViewUrl='' ID='{CB49539A-F215-41D3-8675-8CB6A0FAE9E2…

          <List DocTemplateUrl='' DefaultViewUrl='/product/_catalogs/masterpage/Forms/AllItems.aspx' MobileDefaultViewUrl='' ID='{E5E53853-B2A1-414F-AD18-62B6B274…

          <List DocTemplateUrl='' DefaultViewUrl='/product/Lists/News and Reviews/AllItems.aspx' MobileDefaultViewUrl='' ID='{45A63226-979A-402A-A029-6115AF0BE184…

          <List DocTemplateUrl='' DefaultViewUrl='/product/Pages/Forms/AllItems.aspx' MobileDefaultViewUrl='' ID='{B61087A0-9E16-451D-8132-1038BFFB63F5}' Title='P…

          <List DocTemplateUrl='' DefaultViewUrl='/product/Lists/Web Casts/AllItems.aspx' MobileDefaultViewUrl='' ID='{70F8653B-D81E-4AEE-8336-5A55789EB717}' Titl…

          <List DocTemplateUrl='' DefaultViewUrl='/product/WorkflowTasks/AllItems.aspx' MobileDefaultViewUrl='' ID='{75C8921E-9214-4212-998C-7AF611020D8D}' Title=…

        </Lists>

      </GetListCollectionResult>

    </GetListCollectionResponse>

  </soap:Body>

</soap:Envelope>


Now this is the first example that shows how to manage the namespaces concern with XPath. We will retrieve all the nodes corresponding to the SharePoint lists:

            // Create a new XmlDocument  

            XmlDocument doc = new XmlDocument();

 

            // Load data  

            doc.LoadXml(XmlSring);

            // define namespaces  

            XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);

            ns.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");

            ns.AddNamespace("namespace", "http://schemas.microsoft.com/sharepoint/soap/");

 

            // retrieve the lists nodes  

            XmlNodeList Lists = doc.SelectNodes("//soap:Envelope/soap:Body/namespace:GetListCollectionResponse/namespace:GetListCollectionResult/namespace:Lists", ns);


 - The GetListItems Method returns information about items in the list based on the specified query and the complete SOAP XML returned by the web service looks like this one:

<?xml version="1.0" encoding="utf-8"?>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLS...

    <soap:Body>

        <GetListItemsResponse xmlns="http://schemas.microsoft.com/sharepoint/soap/">

            <GetListItemsResult>

                <listitems xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882' xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882' xmlns:rs='urn:schemas-microsof...

                    <rs:data ItemCount="6">

                        <z:row ows_SilverlightBackgroundURL='http://sharepoint.microsoft.com/PublishingImages/home-2010_beta_banner.jpg' ows_HyperlinkURL='http:// ...

                        <z:row ows_LinkTitle='Enterprise Social Computing with SharePoint' ows_SilverlightBackgroundURL='http://sharepoint.microsoft.com/Publishin...

                        <z:row ows_LinkTitle='Save Money with SharePoint' ows_SilverlightBackgroundURL='http://sharepoint.microsoft.com/PublishingImages/SP_News_S...

                        <z:row ows_LinkTitle='Introducing Microsoft Office 2010 Beta' ows_SilverlightBackgroundURL='http://sharepoint.microsoft.com/PublishingImag...

                        <z:row ows_LinkTitle='Microsoft Office for the Mac SP2' ows_SilverlightBackgroundURL='http://sharepoint.microsoft.com/PublishingImages/SP_...

                        <z:row ows_SilverlightBackgroundURL='http://msn.com' ows_HyperlinkURL='http://msn.com, http://msn.com' ows_HyperlinkXoffset='-50' ows_Hype..

                    </rs:data>

                </listitems>

            </GetListItemsResult>

        </GetListItemsResponse>

    </soap:Body>

</soap:Envelope>


This is the second example that shows how to manage the namespaces concern with XPath. We will retrieve all the nodes corresponding to the items of a SharePoint list:

            // Create a new XmlDocument  

            XmlDocument doc = new XmlDocument();

 

            // Load data  

            doc.LoadXml(XmlString);

 

            // define namespaces  

            XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);

 

            ns.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");

            ns.AddNamespace("namespace", "http://schemas.microsoft.com/sharepoint/soap/");

            ns.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");

 

            // retrieve the list items nodes  

            XmlNodeList data = doc.SelectNodes("//soap:Envelope/soap:Body/namespace:GetListItemsResponse/namespace:GetListItemsResult/namespace:listitems/rs:data", ns);