Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 243
  • Last Modified:

Returning Values from XML string

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
Jackass03
Asked:
Jackass03
  • 12
  • 8
1 Solution
 
ozymandiasCommented:
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
 
Jackass03Author Commented:
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
 
ozymandiasCommented:
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
ozymandiasCommented:
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
 
Jackass03Author Commented:
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
 
ozymandiasCommented:
USE

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

OR

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

BUT NOT

doc.SelectSingleNode("content/main");

0
 
Jackass03Author Commented:
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
 
Jackass03Author Commented:
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
 
ozymandiasCommented:
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
 
ozymandiasCommented:
It must be your xml.
0
 
Jackass03Author Commented:
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
 
ozymandiasCommented:
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
 
Jackass03Author Commented:
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
 
ozymandiasCommented:
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
 
Jackass03Author Commented:
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
 
Jackass03Author Commented:
do you think it could be to do with the line breaks after the <p>'s?
0
 
ozymandiasCommented:
The problem is the xmlns (namespace) attribute in the page_data element start tag.
If you remove this it works fine.
0
 
ozymandiasCommented:
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
 
ozymandiasCommented:
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
 
ozymandiasCommented:
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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 12
  • 8
Tackle projects and never again get stuck behind a technical roadblock.
Join Now