Solved

Querying with XPath in C#

Posted on 2009-07-15
10
1,165 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
10 Comments
 
LVL 75

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 75

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
Turn Insights Into Action

You’ve already invested in ITSM tools, chat applications, automation utilities, and more. Fortify these solutions with intelligent communications so you can drive business processes forward.

With xMatters, you'll never miss a beat.

 
LVL 23

Assisted Solution

by:Tony McCreath
Tony McCreath 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
 
LVL 75

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 75

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 75

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 75

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

Increase Agility with Enabled Toolchains

Connect your existing build, deployment, management, monitoring, and collaboration platforms. From Puppet to Chef, HipChat to Slack, ServiceNow to JIRA, Splunk to New Relic and beyond, hand off data between systems to engage the right people.

Connect with xMatters.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction In my previous article (http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SSIS/A_9150-Loading-XML-Using-SSIS.html) I showed you how the XML Source component can be used to load XML files into a SQL Server database, us…
Browsing the questions asked to the Experts of this forum, you will be amazed to see how many times people are headaching about monster regular expressions (regex) to select that specific part of some HTML or XML file they want to extract. The examp…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

690 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