Solved

Returning Values from XML string

Posted on 2006-11-02
20
212 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 15

Expert Comment

by:ozymandias
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
It must be your xml.
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 

Author Comment

by:Jackass03
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
Introduction Since I wrote the original article about Handling Date and Time in PHP and MySQL (http://www.experts-exchange.com/articles/201/Handling-Date-and-Time-in-PHP-and-MySQL.html) several years ago, it seemed like now was a good time to updat…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

763 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

5 Experts available now in Live!

Get 1:1 Help Now