Solved

Returning Values from XML string

Posted on 2006-11-02
20
218 Views
Last Modified: 2013-11-19
Hi

I'm querying my sql database, 1 colomn out of 1 table - which returns 300 rows.

The content out of the colomn is an XML string in the format:

<?xml version="1.0"?>
      <page_data xmlns="">
            <template></template>
            <template_data></template_data>
            <content>
                  <main><![CDATA[<p>I would like to return this data</p>]]></main>
                  <right><![CDATA[<P>i dont want to return this</P>]]></right>
                  </content>
      </page_data>

Basically in my aspx, i'm querying the data but would now like to just return the <main> element from the xml string.

So if I have a string sXMLString with the above XML in - how could i just return the data from the <main> element.

Hope someone can help :)

0
Comment
Question by:Jackass03
  • 12
  • 8
20 Comments
 
LVL 15

Expert Comment

by:ozymandias
ID: 17858288
XmlDocument doc = new XmlDocument();
doc.LoadXml(sXmlString);
XmlNode node = doc.DocumentElement.SelectSingleNode("content/main");

// node now contains  <main><![CDATA[<p>I would like to return this data</p>]]></main>
// If you want the actual xml of the node then you can use

string s = node.OuterXml;

// if you want the actual text inside it you can use

string t = node.InnerText;

0
 

Author Comment

by:Jackass03
ID: 17858347
Hi

Many thanks for the super fast response!

Got the following error:

Object reference not set to an instance of an object.

@
string t = node.InnerText;

Yeah its the InnerText that i want :)

ANy ideas on the error?
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 17858506
Here is my code...it works fine :

class Class1
      {
            [STAThread]
            static void Main(string[] args)
            {
                  string xml = "<?xml version='1.0'?><page_data xmlns=''><template></template><template_data></template_data><content><main><![CDATA[<p>I would like to return this data</p>]]></main><right><![CDATA[<P>i dont want to return this</P>]]></right></content></page_data>";
                  XmlDocument doc = new XmlDocument();
                  doc.LoadXml(xml);
                  XmlNode node = doc.DocumentElement.SelectSingleNode("content/main");
                  Console.WriteLine(node.InnerText);
                  Console.ReadLine();
            }
      }
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 15

Expert Comment

by:ozymandias
ID: 17858533
Your error suggests that SelectSingleNode returned null because it could not find a node at the Xpath you specified, so either your xml is not in the formnat you have suggested or the xpath you have is wrong ("content/main") or you have called SelectSingleNode on the doc itself and not on the doc.DocumentElement.
0
 

Author Comment

by:Jackass03
ID: 17858612
Hiya

Thanks for your reply

I have changed my sql query so it only returns one record.... i've checked the xpath and its ok and I'm using the SelectSingleNode on the doc - any more ideas?
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 17858653
USE

doc.DocumentElement.SelectSingleNode("content/main");

OR

XmlNode node = doc.SelectSingleNode("page_data/content/main");

BUT NOT

doc.SelectSingleNode("content/main");

0
 

Author Comment

by:Jackass03
ID: 17858665
Missed out a CDATA but i dont think it affects things - here is my xml string...

sXMLString =

<?xml version="1.0"?>
      <page_data xmlns="http://">
            <template>template.htt</template>
            <template_data><![CDATA[]]></template_data>
            <content>
                  <main><![CDATA[<P>I would like to return this data</P>]]></main>
                  <right><![CDATA[I don't want to return this data]]></right>
            </content>
      </page_data>
0
 

Author Comment

by:Jackass03
ID: 17858743
just tried your code and it worked fine - its the same as mine apart from my returns the xml string from the database.... must be something to do with that !

When i query the database via query analyser i get the xml as posted earlier
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 17858789
Still works :

class Class1
      {
            [STAThread]
            static void Main(string[] args)
            {
                  try{
                        string xml = @"<?xml version='1.0'?>
                                                      <page_data xmlns=''>
                                                            <template>template.htt</template>
                                                            <template_data><![CDATA[]]></template_data>
                                                            <content>
                                                                  <main><![CDATA[<P>I would like to return this data</P>]]></main>
                                                                  <right><![CDATA[I don't want to return this data]]></right>
                                                            </content>
                                                      </page_data>";
                        XmlDocument doc = new XmlDocument();
                        doc.LoadXml(xml);
                        
                        XmlNode node = doc.DocumentElement.SelectSingleNode("content/main");
                        if (node == null){
                              Console.WriteLine("node is null");
                        }else{
                              Console.WriteLine(node.InnerText);
                        }
                        
                  }catch(Exception ex){
                        Console.WriteLine(ex.StackTrace);
                  }
                  Console.ReadLine();
            }
      }
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 17858804
It must be your xml.
0
 

Author Comment

by:Jackass03
ID: 17858811
To get the xml data from the database, i'm simply connecting and using the SQLDataReader to get the content field (which has the xml string)

string sXMLString = objRdr["content"].ToString();
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 17858840
Can you get that sXMLString and post it unaltered or write it to a file and email it to me at ozymandias [at] chainreactors [dot] co [dot] uk
0
 

Author Comment

by:Jackass03
ID: 17858885
I have just grabbed the output from the database and manually put it in a string to parse.

I had to change all the "s to 's to get it to compile.

I then had to remove the url from the page_data xmlns to get it to work for onr string.

how can i change the " s to ' s ?  
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 17858937
You should not have to do that.
Either xml is well-formed or it is not.
If I can see the actual xml I might be able to tell you what to do.
0
 

Author Comment

by:Jackass03
ID: 17859061
Here is the exact xml - copied from my sql query

<?xml version="1.0"?><page_data xmlns="http://testbox/Edit/"><template>template.htt</template><template_data><![CDATA[]]></template_data><content><main><![CDATA[<P>This is exactually how the xml is displayed</P>
<P>This is exactually how the xml is displayed</P>
<P>This is exactually how the xml is displayed <a href="www.google.co.uk">Link"></a></P>]]></main><right><![CDATA[<P>This is the data on the right hand side of the page</P>]]></right></content></page_data>
0
 

Author Comment

by:Jackass03
ID: 17859068
do you think it could be to do with the line breaks after the <p>'s?
0
 
LVL 15

Accepted Solution

by:
ozymandias earned 100 total points
ID: 17859277
The problem is the xmlns (namespace) attribute in the page_data element start tag.
If you remove this it works fine.
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 17859530
OK. The namespace must be messing with the xpath somehow but I'm not sure how or why.

Here is an alternative way of getting round the problem using the GetElementsByTagName() method instead of SelectSingleNode.

class Class1
      {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main(string[] args)
            {
                  try{
                        string xml = "<?xml version=\"1.0\"?><page_data xmlns=\"http://testbox/Edit/\"><template>template.htt</template><template_data><![CDATA[]]></template_data><content><main><![CDATA[<P>This is exactually how the xml is displayed</P><P>This is exactually how the xml is displayed</P><P>This is exactually how the xml is displayed <a href=\"www.google.co.uk\">Link\"></a></P>]]></main><right><![CDATA[<P>This is the data on the right hand side of the page</P>]]></right></content></page_data>";
                        XmlDocument doc = new XmlDocument();
                        doc.LoadXml(xml);
                        XmlNodeList nodes = doc.GetElementsByTagName("main");
                        foreach(XmlNode node in nodes){
                              Console.WriteLine(node.InnerText);
                        }
                        
                  }catch(Exception ex){
                        Console.WriteLine(ex.StackTrace);
                  }
                  Console.ReadLine();
            }
      }
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 17859786
OK. I have finally worked this out.
Man it's a pain !

The default namespace declaratoin you have used has no prefix but it puts all sub elements in a namespace.

This xpath "content/main" looks for any main element in any content element both of which have no namespace....so they are not found because your element has a namespace but no way of identifying that namespace.

So, we add a namespace manager that will create one for us  and, bingo, it works....

class Class1
     {
          [STAThread]
          static void Main(string[] args)
          {
               try{
                    string xml = "<?xml version=\"1.0\"?><page_data xmlns=\"http://testbox/Edit/\"><template>template.htt</template><template_data><![CDATA[]]></template_data><content><main><![CDATA[<P>This is exactually how the xml is displayed</P><P>This is exactually how the xml is displayed</P><P>This is exactually how the xml is displayed <a href=\"www.google.co.uk\">Link\"></a></P>]]></main><right><![CDATA[<P>This is the data on the right hand side of the page</P>]]></right></content></page_data>";
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(xml);
                    XmlNamespaceManager xmlnsm = new XmlNamespaceManager(doc.NameTable);
                    xmlnsm.AddNamespace("x","http://www.thing.com");
                    XmlNode node = doc.SelectSingleNode("x:page_data/x:content/x:main");
                    Console.WriteLine(node.InnerText);                  
               }catch(Exception ex){
                    Console.WriteLine(ex.StackTrace);
               }
               Console.ReadLine();
          }
     }
0
 
LVL 15

Expert Comment

by:ozymandias
ID: 17860790
BTW, there is a typo in the above :

 xmlnsm.AddNamespace("x","http://www.thing.com");


should be

 xmlnsm.AddNamespace("x","http://testbox/Edit/");
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Diagnostics with Net and Net.Sockets 2 31
designing in object programming 12 94
how to check to see if datatable has headers or not 2 34
C# Gridview 1 47
Preface This is the third article about the EE Collaborative Login Project. A Better Website Login System (http://www.experts-exchange.com/A_2902.html) introduces the Login System and shows how to implement a login page. The EE Collaborative Logi…
Shoutout to Emily Plummer (http://www.experts-exchange.com/members/eplummer26.html) for giving me this article! She did most of it, I just finished it up and posted it for her :)    Introduction In a previous article (http://www.experts-exchang…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:

839 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