Solved

Reading XML from a String variable in C#

Posted on 2010-11-30
25
1,966 Views
Last Modified: 2013-11-11
A  String Variable 'str' is having following value
<?xml version="1.0" encoding="utf-8"?>
<Transaction>
  <firstName>FirstName</firstName>
  <lastName>LastName</lastName>
  <street>Street</street>
  <zip>54321</zip>
  <city>City</city>
  <country>LV</country>
  <email>kumar@gmail.com</email>
  <ip>123.124.125.126</ip>
  <value>1000</value>
  <currency>USD</currency>
  <productName>Product Name</productName>
  <productUrl>www.test.com</productUrl>
  <orderNumber>9865391</orderNumber>
</Transaction>

How can I read it so that i get firstName, lastName etc.
0
Comment
Question by:Dinesh Kumar
  • 13
  • 8
  • 2
  • +1
25 Comments
 
LVL 12

Expert Comment

by:HugoHiasl
ID: 34238857
You can fill it to an XML DOM by using

XmlDocument doc = new XmlDocument();
doc.Parse(<yourstring>);
   
XmlElement root = doc.DocumentElement;

After this you can access it with standard Xpath:

root["firstName"].InnerText;
root["lastName"].InnerText;
0
 

Author Comment

by:Dinesh Kumar
ID: 34238888
doc.Parse in c# does not exist.
0
 
LVL 12

Expert Comment

by:HugoHiasl
ID: 34238924
Hmm.. Sorry.. This was Linq

Use

doc.LoadXml(<yourstring>)

instead.
0
 

Author Comment

by:Dinesh Kumar
ID: 34245598
HugoHias:, can you replace Parse with LoadXml so that I can accept your solution as a whole at one place.
0
 

Author Comment

by:Dinesh Kumar
ID: 34247537
Problem coming in doc.LoadXml(<yourstring>)
System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.
   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
   at System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
   at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XmlLoader.Load(XmlDocument doc, XmlReader reader, Boolean preserveWhitespace)
   at System.Xml.XmlDocument.Load(XmlReader reader)
   at System.Xml.XmlDocument.LoadXml(String xml)
   at ImsWebService.Transaction.CREATE(HttpContext context) in some file.

0
 
LVL 2

Expert Comment

by:jaya_banbah
ID: 34247787
Hi,

This exception is mostly because of some white spaces at the starting position.My guess is that when you are placing it in the string variable , there are some spaces in the starting position.
0
 

Author Comment

by:Dinesh Kumar
ID: 34248090

I tried trim as follows..
byte[] PostData = context.Request.BinaryRead(context.Request.ContentLength);
                //Convert the bytes to string using Encoding class
                string str = Encoding.UTF8.GetString(PostData);
                WriteResponse(str);
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(str);
                XmlElement root = doc.DocumentElement;                
                WriteResponse(root["email"].InnerText.Trim());
but its not working.

whenever I try the following root["email"].InnerText it gives the error Data at the root level is invalid. Line 1, position 1
0
 

Author Comment

by:Dinesh Kumar
ID: 34248171
Now the xml value is:
<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Transaction>\r\n  <firstName>DineshKumar</firstName>\r\n  <lastName>LastName</lastName>\r\n  <street>Street</street>\r\n  <zip>54321</zip>\r\n  <city>City</city>\r\n  <country>LV</country>\r\n  <email>kumar@gmail.com</email>\r\n  <ip>123.124.125.126</ip>\r\n  <value>10010</value>\r\n  <currency>USD</currency>\r\n  <productName>Product Name</productName>\r\n  <productUrl>www.test.com</productUrl>\r\n  <orderNumber>1231673</orderNumber>\r\n  <cardname>dineshKumar</cardname>\r\n  <cardnr>4314229999999913</cardnr>\r\n  <validMONTH>01</validMONTH>\r\n  <validYEAR>13</validYEAR>\r\n  <cvc2>123</cvc2>\r\n</Transaction>
0
 

Author Comment

by:Dinesh Kumar
ID: 34248323
isn't there alternative of doc.LoadXml(<yourstring>)?
0
 

Author Comment

by:Dinesh Kumar
ID: 34248539
Now The  XML is:
<?xml version='1.0' encoding='utf-8'?><Transaction><firstName>DineshKumar</firstName><lastName>LastName</lastName><street>Street</street><zip>54321</zip><city>City</city><country>LV</country><email>kumar@gmail.com</email><ip>123.124.125.126</ip><value>10010</value><currency>USD</currency><productName>Product Name</productName><productUrl>www.test.com</productUrl><orderNumber>123114173</orderNumber><cardname>dineshKumar</cardname><cardnr>4314229999999913</cardnr><validMONTH>01</validMONTH><validYEAR>13</validYEAR><cvc2>123</cvc2></Transaction>
0
 
LVL 2

Expert Comment

by:jaya_banbah
ID: 34253970
I tried your string and it executed very well for me.
I am posting the code below:-
0
 
LVL 2

Assisted Solution

by:jaya_banbah
jaya_banbah earned 124 total points
ID: 34253974
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace XmlDom_try
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            XmlDocument xdoc = new XmlDocument();

            String str = @"<?xml version=" + '"' + "1.0" + '"' + " encoding=" + '"' + "utf-8" + '"' + "?>" +

   " <Transaction>  <firstName>FirstName</firstName>   <lastName>LastName</lastName>   <street>Street</street>"+
  "<zip>54321</zip>   <city>City</city>  <country>LV</country>  <email>kumar@gmail.com</email>"+
  "<ip>123.124.125.126</ip> <value>1000</value> <currency>USD</currency> <productName>Product Name</productName>"+
  "<productUrl>www.test.com</productUrl>   <orderNumber>9865391</orderNumber> </Transaction>";
            label2.Text = str;
         xdoc.LoadXml(str);

            XmlElement root = xdoc.DocumentElement;



            label1.Text= root["firstName"].InnerText;
label2.Text=root["lastName"].InnerText;
        }
    }
}

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 2

Expert Comment

by:jaya_banbah
ID: 34253983
I am sorry couldn't post the code in "Code" section as provided in the site.My system is not working fine for now.
0
 

Author Comment

by:Dinesh Kumar
ID: 34255371
  what is happening here
   XmlElement root = xdoc.DocumentElement;
    label1.Text= root["firstName"].InnerText;

0
 

Author Comment

by:Dinesh Kumar
ID: 34256401
whenever I try to access the first approach in the processrequest handler:
I get the error like 'Data at the root level is invalid. Line 1, position 1'
so I thought that there might be some problem in generating the xml with code so I generated with the second approach. which worked well.

Do you see any drawback of it?
FIRST APPROACH(WHICH IS NOT WORKING)

 MemoryStream mStream = new MemoryStream();
        //XmlTextWriter xmlWriter = new XmlTextWriter(@"C:\Employee.xml", Encoding.UTF8);
        XmlTextWriter xmlWriter = new XmlTextWriter(mStream, Encoding.UTF8);
        xmlWriter.Formatting = Formatting.Indented;        
        xmlWriter.WriteStartDocument();
        xmlWriter.WriteStartElement("Transaction");
        
        xmlWriter.WriteStartElement("firstName");
        xmlWriter.WriteString(firstName);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("lastName");
        xmlWriter.WriteString(lastName);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("street");
        xmlWriter.WriteValue(street);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("zip");
        xmlWriter.WriteString(zip);
        xmlWriter.WriteEndElement();

        xmlWriter.WriteStartElement("city");
        xmlWriter.WriteString(city);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("country");
        xmlWriter.WriteString(country);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("email");
        xmlWriter.WriteString(email);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("ip");
        xmlWriter.WriteString(ip);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("value");
        xmlWriter.WriteString(value);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("currency");
        xmlWriter.WriteString(currency);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("productName");
        xmlWriter.WriteString(productName);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("productUrl");
        xmlWriter.WriteString(productUrl);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("orderNumber");
        xmlWriter.WriteString(orderNumber);
        xmlWriter.WriteEndElement();

        xmlWriter.WriteStartElement("cardname");
        xmlWriter.WriteString(cardname);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("cardnr");
        xmlWriter.WriteString(cardnr);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("validMONTH");
        xmlWriter.WriteString(validMONTH);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("validYEAR");
        xmlWriter.WriteString(validYEAR);
        xmlWriter.WriteEndElement();
        xmlWriter.WriteStartElement("cvc2");
        xmlWriter.WriteString(cvc2);
        xmlWriter.WriteEndElement();

        xmlWriter.WriteEndElement();
        xmlWriter.WriteEndDocument();
        xmlWriter.Flush();
        xmlWriter.Close();
        return mStream.ToArray();

SECOND APPROACH(WHICH IS WORKING):
   String postData = "<?xml version='1.0' encoding='utf-8'?>"+
        "<Transaction>"+
        "<firstName>"+firstName+"</firstName>"+
        "<lastName>" + lastName + "</lastName>" +
        "<street>" + street + "</street>" +
        "<zip>" + zip + "</zip>" +
        "<city>" + city + "</city>" +
        "<country>" + country + "</country>" +
        "<email>" + email + "</email>" +
        "<ip>" + ip + "</ip>" +
        "<value>" + value + "</value>" +
        "<currency>" + currency + "</currency>" +
        "<productName>" + productName + "</productName>" +
        "<productUrl>" + productUrl + "</productUrl>" +
        "<orderNumber>" + orderNumber + "</orderNumber>" +
        "<cardname>" + cardname + "</cardname>" +
        "<cardnr>" + cardnr + "</cardnr>" +
        "<validMONTH>" + validMONTH + "</validMONTH>" +
        "<validYEAR>" + validYEAR + "</validYEAR>" +
        "<cvc2>" + cvc2 + "</cvc2>" +
        "</Transaction>";
        byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(postData);
        return byteArray;

Open in new window

0
 
LVL 2

Expert Comment

by:jaya_banbah
ID: 34256769
I tried you first approach and it did give me the error.When I check the value of the " postdata" string variable , it is prefixed with a wrong char,hence the error.
0
 
LVL 2

Assisted Solution

by:jaya_banbah
jaya_banbah earned 124 total points
ID: 34256820
your First Approach works for me in the below mentioned code:-

 string str = Encoding.UTF8.GetString(mStream.ToArray());
           WriteResponse(str);  
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(str.Remove(0,1));

            XmlElement root = doc.DocumentElement;
            WriteResponse(root["email"].InnerText.Trim());
           
0
 

Author Comment

by:Dinesh Kumar
ID: 34256888
jaya_banbah:
I tried you first approach and it did give me the error.When I check the value of the " postdata" string variable , it is prefixed with a wrong char,hence the error.

can you please send me the screenshot showing me the wrong char?
0
 

Author Comment

by:Dinesh Kumar
ID: 34256907
if possible, what was the code error in first approach! very keen to know that
0
 
LVL 2

Expert Comment

by:jaya_banbah
ID: 34263269
here's the screenshot for postdata string: Screenshot with the erroneous char in the begininning
0
 
LVL 2

Expert Comment

by:jaya_banbah
ID: 34263277
the error was the same that you are getting for that code..
0
 

Author Comment

by:Dinesh Kumar
ID: 34264366
1. converts to bytes with UTF8 encoding
2. bytes to string with UTF8 encoding  is creating problem of invalid char as seen in the attached image.

  I am still struggling why this invalid char is coming in the following code:
        MemoryStream mStream = new MemoryStream();
        //XmlTextWriter xmlWriter = new XmlTextWriter(@"C:\Employee.xml", Encoding.UTF8);
        XmlTextWriter xmlWriter = new XmlTextWriter(mStream, Encoding.UTF8);
        xmlWriter.Formatting = Formatting.Indented;        
        xmlWriter.WriteStartDocument();
        xmlWriter.WriteStartElement("Transaction");
        .....
        ....
invalid-char.JPG
0
 
LVL 9

Assisted Solution

by:AnilKumarSharma
AnilKumarSharma earned 126 total points
ID: 34264488
The UTF-8 encoding is clearly the way to go for using Unicode. In order to allow the automatic detection of the byte order, it has become customary on some platforms notably Win32) to start every Unicode file with the character U+FEFF (ZERO WIDTH NO-BREAK SPACE), also known as the Byte-Order Mark (BOM). Its byte-swapped equivalent U+FFFE is not a valid Unicode character, therefore it helps to unambiguously distinguish the Bigendian and Littleendian variants of UTF-16 and UTF-32.

A good encoding converter will also offer options for adding or removing the BOM:
•Unconditionally prefix the output text with U+FEFF.
•Prefix the output text with U+FEFF unless it is already there.
•Remove the first character if it is U+FEFF.
•The bytes 0xFE and 0xFF are never used for text in the UTF-8 encoding (as they are used for marking, see above)
0
 
LVL 9

Accepted Solution

by:
AnilKumarSharma earned 126 total points
ID: 34264689
So the first charcter you see in your string is BOM.
Actually if using xmlparser,  XMLParser recognize BOM and automatically remove it. If you consider to remove BOM, then you probably have more problems with your current method than just trimming the byte order mark.
You can achieve the same as

private readonly string _byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
 if (str.StartsWith(_byteOrderMarkUtf8))
{
       str= str.Remove(0, _byteOrderMarkUtf8.Length);
}


0
 

Author Closing Comment

by:Dinesh Kumar
ID: 34280038
Thank you very much.
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Expando 4 35
Trouble with References... 5 25
XSLT Help 12 21
Close word object 13 21
For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

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

22 Experts available now in Live!

Get 1:1 Help Now