Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Reading XML from a String variable in C#

Posted on 2010-11-30
25
Medium Priority
?
2,200 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
[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
  • 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
Cloud Training Guides

FREE GUIDES: In-depth and hand-crafted Linux, AWS, OpenStack, DevOps, Azure, and Cloud training guides created by Linux Academy instructors and the community.

 

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 496 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
 
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 496 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 504 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 504 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

RHCE - Red Hat OpenStack Prep Course

This course will provide in-depth training so that students who currently hold the EX200 & EX210 certifications can sit for the EX310 exam. Students will learn how to deploy & manage a full Red Hat environment with Ceph block storage, & integrate Ceph into other OpenStack service

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…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

670 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