Sunday, May 1, 2011

Querying List Data From SharePoint Web Services

Has anybody ever successfully written code to extract data from a SharePoint 2007 list (specifically, an InfoPath form library) using the GetListItems() method in the http:///_vti_bin/lists.asmx service (and lived to tell about it)? It returns some of the worst XML I've seen in my life (it's not even compliant XML). Is there some easy way to parse the data in C# or am I going to need to parse through it manually?

Any help on this would be greatly appreciated.

From stackoverflow
  • InfoPath cannot handle the XML from GetListItems within the Lists web service. With InfoPath 2007 you have two options:

    1. Use the InfoPath 2007 SharePoint data connection which does not allow for filtering of list content. You have to grab all content back to the client (or server if it is InfoPath Forms Services) and then filter it within your InfoPath rules.
    2. Write a web service that lives within SharePoint that returns data in a format that InfoPath 2007 can digest. I have done this before where you can pass it a list name and CAML query and set of fields and it will return rows of name/value pairs. Unfortunately, I am not allowed to share this code at this time.
    senfo : The consumer is actually a C# console application. I'm convinced building a custom web service that returns a strongly typed collection of List items will be infinitely easier than the native approach. Thank you for the response.
  • Sure it is not the prettiest way of doing things, but it simply a matter of getting the correct examples.

    I have used the following code to get "stuff" out of a get lists query.

    public static XmlNodeList XpathQuery(XmlNode xmlToQuery, string xPathQuery)
    {
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xmlToQuery.OuterXml);
        XmlNamespaceManager mg = new XmlNamespaceManager(doc.NameTable);
        mg.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/soap/");
        mg.AddNamespace("z", "#RowsetSchema");                                   
        mg.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");
        mg.AddNamespace("y", "http://schemas.microsoft.com/sharepoint/soap/ois");
        mg.AddNamespace("w", "http://schemas.microsoft.com/WebPart/v2");
        mg.AddNamespace("d", "http://schemas.microsoft.com/sharepoint/soap/directory");
        return doc.SelectNodes(xPathQuery, mg);
    }
    

    Calling it using

        XmlNode items = lists.GetListItems(listName, string.Empty, listQuery, listViewFields, string.Empty, listQueryOptions, g.ToString());
        foreach (XmlNode listItem in SPCollection.XpathQuery(items, "//sp:listitems/rs:data/z:row"))
        {
            XmlAttribute id = listItem.Attributes["ows_Id"];
            if (id != null)
            {
                pageId = id.Value;                    
            }
    
        }
    

    The example does not do a whole lot, but hopefully it gives you an idea of how to go about getting the data out. Yes I intensly dislike the whole namespace issue with XPathQueries, but what are you gonna do.

    I am just not that interested in re-writing the SharePoint web services, especially as testing and releasing in our environment is weeks worth of effort in and of itself. Sometimes though, there is no option. E.g. if you want to access the custom property bag of an SPWeb or create a SiteCollection using a specific Site Template and content database (or any of the other million things that are not implemented in the web services). However, for simple list access, the webservices seem fine.

    senfo : Can I ask a really stupid question? How did you know about those namespaces?
    senfo : Nevermind, I found them. They're in the response from SharePoint.

0 comments:

Post a Comment