Solved

Querying with XPath in C#

Posted on 2009-07-15
10
1,120 Views
Last Modified: 2013-11-11
Hi all,

I am trying to connect to a Sharepoint list and extract data from it with the GetListItems method into a XmlNode.  I am able to get as far as connecting to the Sharepoint List and extract the list items.  But it comes back in an XML fragment like this:

<listitems xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
   xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
   xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"
   xmlns="http://schemas.microsoft.com/sharepoint/soap/">
   <rs:data ItemCount="4">
      <z:row ows_Number_Field="6555.00000000000"
         ows_Created="2003-06-18T03:41:09Z"
         ows_ID="3" ows_owshiddenversion="3" />
      <z:row ows_Number_Field="78905456.0000000"
         ows_Created="2003-06-18T17:15:58Z"
         ows_ID="4" ows_owshiddenversion="2" />
         ...
   </rs:data>
</listitems>

Is there a way to run an Xpath query to filter out just the information in:
z:row ows_Number_Field="78905456.0000000"

Thanks in advance.

pwit
0
Comment
Question by:Pwit
  • 6
  • 3
10 Comments
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 24864810
I imagine your XPath should be something like

    //listitems/rs:data/z:row[@ows_Number_Field='78905456.0000000']
0
 

Author Comment

by:Pwit
ID: 24865478
Hi Kaufmed,

Thanks for the quick reply, but when I build and try to get the run the program I get this error:

Namespace Manager or XsltContext needed. This query has a prefix, variable, or user-defined function.

I tried to look this up at MSDN, but this was all I could find:

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("bk", "urn:newbooks-schema");

Do I have to apply this to my function or is there something I am missing?  Thanks again.

pwit
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 24865785
I'm not completely sure of the "best practice" way to do it, but when I had something similar, I did have to add the namesapce manager and namespaces to the reader.
0
 
LVL 23

Assisted Solution

by:Tiggerito
Tiggerito earned 150 total points
ID: 24868246
Yep, you need to handle the namespaces:

http://support.microsoft.com/kb/318545
0
 

Author Comment

by:Pwit
ID: 24871317
Hi guys,

I been tinkering around with the namespace stuff all morning, but haven't been able to get my code to generate anything useful.  Here is the xml fragment I been able to generate and afterwards convert to an xmldocument.  But I am still clueless on how to assign the namespaces and query out something useful, like the ows_title="Test tile" in the xml below:

<listitems xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema" xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<rs:data ItemCount="2">
<z:row ows_Title="Test tile" ows_Message="test Message" ows_MetaInfo="1;#" ows__ModerationStatus="0" ows__Level="1" ows_ID="1" ows_owshiddenversion="2" ows_UniqueId="1;#{E59FDB30-85AD-462E-B921-A16AAED789C6}" ows_FSObjType="1;#0" ows_Created="2009-07-13 14:31:22" ows_FileRef="1;#sites/support/it/development/Lists/TargetList/1_.000" />
<z:row ows_Title="pwit" ows_Message="man" ows_MetaInfo="2;#" ows__ModerationStatus="0" ows__Level="1" ows_ID="2" ows_owshiddenversion="1" ows_UniqueId="2;#{DF0FD21B-1A9A-4038-8829-C37697A80898}" ows_FSObjType="2;#0" ows_Created="2009-07-13 14:41:28" ows_FileRef="2;#sites/support/it/development/Lists/TargetList/2_.000" />
</rs:data>
</listitems>


Also attached is the code that I have so far.  Thanks for your help.

pwit
private void takeListItem()

        {

            chi02devmoss.Lists listService = new chi02devmoss.Lists();

            listService.Credentials = System.Net.CredentialCache.DefaultCredentials;
 

            String listName = "TargetList";

            XmlDocument xmlDoc = new XmlDocument();
 

            XmlNode ndQuery = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");

            XmlNode ndViewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");

            XmlNode ndQueryOptions = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions", "");
 

            ndQueryOptions.InnerXml = "<IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns>" + "<DateInUtc>FALSE</DateInUtc>";

            ndViewFields.InnerXml = "<FieldRef Name='Title' /> <FieldRef Name='Message'/>";

            //ndQuery.InnerXml = "<Where><And><Gt><FieldRef Name='Title'/>" + "<Value Type='Number'>5000</Value></Gt><Gt><FieldRef Name='Message'/>" + "<Value Type = 'DateTime'>2003-07-03T00:00:00</Value></Gt></And></Where>";
 

            try

            {

                XmlNode ndListItems = listService.GetListItems(listName, null, ndQuery, ndViewFields, null, ndQueryOptions, null);

                //MessageBox.Show(ndListItems.OuterXml);

                XmlDocument x = new XmlDocument();
 

                x.LoadXml(ndListItems.OuterXml);

                System.Xml.XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(x.NameTable);
 

                xmlnsManager.AddNamespace("first", "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882");

                xmlnsManager.AddNamespace("second", "uuid:C2F41010-65B3-11d1-A29F-00AA00C14882");

                xmlnsManager.AddNamespace("third", "urn:schemas-microsoft-com:rowset");
 

                System.Xml.XmlNodeList test;

                test = x.SelectNodes("//first:row[@ows_Title]", xmlnsManager);
 

                foreach (XmlNode t in test)

                {

                    MessageBox.Show(t.InnerXml);

                }
 

            }
 

            catch (System.Web.Services.Protocols.SoapException ex)

            {

                MessageBox.Show("Message:\n" + ex.Message + "\nDetail:\n" + ex.Detail.InnerText + "\nStackTrace:\n" + ex.StackTrace);

            }
 

        }

Open in new window

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 24871389
Where you have "first," "second" and "third," you should have the prefix that is associated with the uid. Something like:
xmlnsManager.AddNamespace("s", "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882");

xmlnsManager.AddNamespace("dt", "uuid:C2F41010-65B3-11d1-A29F-00AA00C14882");

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

Open in new window

0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 24871409
Then your XPath would be:
test = x.SelectNodes("z:row[@ows_Title]", xmlnsManager);

Open in new window

0
 
LVL 74

Accepted Solution

by:
käµfm³d   👽 earned 350 total points
ID: 24871421
Addition to previous post.
xmlnsManager.AddNamespace("s", "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882");

xmlnsManager.AddNamespace("dt", "uuid:C2F41010-65B3-11d1-A29F-00AA00C14882");

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

xmlnsManager.AddNamespace("z", "#RowsetSchema");

Open in new window

0
 

Author Comment

by:Pwit
ID: 24872918
Thanks kaufmed, those namespaces worked like a charm and after changing the xpath to "//z:row", everything started working.  Thanks again for all your help!
XmlNode ndListItems = listService.GetListItems(listName, null, ndQuery, ndViewFields, null, ndQueryOptions, null);

                

                System.Xml.XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(xmlDoc.NameTable);

 

               xmlnsManager.AddNamespace("s", "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882");

xmlnsManager.AddNamespace("dt", "uuid:C2F41010-65B3-11d1-A29F-00AA00C14882");

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

xmlnsManager.AddNamespace("z", "#RowsetSchema");

 

                System.Xml.XmlNodeList test;

                test = x.SelectNodes("//z:row", xmlnsManager);

 

                foreach (XmlNode t in test)

                {

                    MessageBox.Show(t.Attributes["ows_Title"].InnerText);

                }

 

Open in new window

0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 24873252
Cool. I'm still kind of noob-ish when it comes to XML so I wasn't completely sure about the "//". But glad to help nonetheless :)
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
This article is for Object-Oriented Programming (OOP) beginners. An Interface contains declarations of events, indexers, methods and/or properties. Any class which implements the Interface should provide the concrete implementation for each Inter…
This video discusses moving either the default database or any database to a new volume.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now