0

I tried a lot but am not able to get values from xml string, xml string is

<UtilityRateSummaries SchemaVersion="1.0">
 <Utility UtilityId="81" UtilityName="Pacific Gas and Electric Company (PG&E)">
  <Rate Id="238" Name="Residential Service (Rate E1 Area Y Code B)" Sector="Residential" Metering="OptionalNetMetering" IsDefault="true" IsTimeOfUse="false"/>
 </Utility>
</UtilityRateSummaries>

I want all values from this xml file,

I'm using following class

[DataContract]
public class getPowerBillRateData
{

    [DataMember]
    public string UtilityId { get; set; }
    [DataMember]
    public string UtilityName { get; set; }
    [DataMember]
    public string RateId { get; set; }
    [DataMember]
    public string RateName { get; set; }
    [DataMember]
    public string RateSector { get; set; }
    [DataMember]
    public string RateMetering { get; set; }

    [DataMember]
    public string IsDefault { get; set; }
    [DataMember]
    public string IsTimeofUse { get; set; }

}

I've tried following code, but none is working.

PowerBillRate.UtilityName = xmlDoc.DocumentElement["Rate"].ChildNodes[0].InnerText;

code for getting xml

XmlDocument xmlDoc = new XmlDocument();

        using (var client = new CookieAwareWebClient())
        {
            Uri uri = new Uri("https://www.mywebserviceurl.com/Services.svc/Rate/" + 238 + "");
            client.Credentials = new NetworkCredential("myUsername", "myPassword");
            strFetchResData = client.DownloadString(uri);
            xmlDoc.LoadXml(strFetchResData);
        }
2
  • Please post the code you use for loading the XML file/string into your xmlDoc object. Commented Dec 3, 2013 at 10:18
  • What error are you getting? Commented Dec 3, 2013 at 10:57

3 Answers 3

2

Some characters like & have a special meaning in XML and you can't use them directly. You should replace it with &amp;. If you sure you don't have entity references in your xml, then simple String.Replace will do the job:

xml_string = xml_string.Replace("&", "&amp;");

Back to parsing. You can use LINQ to XML:

var xdoc = XDocument.Parse(xml_string);
var utility = xdoc.Root.Element("Utility");

var data = new getPowerBillRateData();
data.UtilityId = (string)utility.Attribute("UtilityId");
data.UtilityName = (string)utility.Attribute("UtilityName");

var rate = utility.Element("Rate");
data.RateId = (string)rate.Attribute("Id");
data.RateName = (string)rate.Attribute("Name");
data.RateSector = (string)rate.Attribute("Sector");
//etc

Also I suggest you to use better naming and more appropriate data types for your data (integer, boolean):

[DataContract]
public class Utility
{
    [DataMember]
    public int Id { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public Rate Rate { get; set; }
}

[DataContract]
public class Rate
{
    [DataMember]
    public int Id { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string Sector { get; set; }
    [DataMember]
    public string Metering { get; set; }    
    [DataMember]
    public bool IsDefault { get; set; }
    [DataMember]
    public bool IsTimeofUse { get; set; }    
}
Sign up to request clarification or add additional context in comments.

7 Comments

Better yet - use XmlSerializer and decorate the business class do be deserializable directly from xml response.
@OndrejSvejdar agree, default (de)serialization is better than manual parsing
@Sumit What error? Have you looked up what that message means?
@SumitChourasia you have incorrect token in your xml &E. Ampersands should be written as &amp; See updated answer
but I'm getting this xml from third party, i can't make changes in xml format.
|
0

XmlSerializer is the way to go, the code is clearer and much faster than LINQ. I've used LINQ here to print the value of one attribute and the IEnumerable should help you get the rest of the elements and their attributes.

XDocument xDoc = XDocument.Parse(xml);
XElement root = xDoc.Root;
Console.WriteLine(root.Attribute((XName)"SchemaVersion").Value);
IEnumerable<XElement> elements = root.Descendants();

Comments

0

It depends on what you want to do with data, but with 'Serializable', which mentioned before, makes it very easy to handle/process data

[Serializable]
[XmlRoot("UtilityRateSummaries")]
public class UtilityRateSummaries
{
    [XmlElement("Utility")]
    public Utility Utility { get; set; }
    [XmlElement("Rate")]
    public Rate Rate { get; set; }
}

public class Utility
{
    [XmlAttribute]
    public string UtilityId { get; set; }
    [XmlAttribute]
    public string UtilityName { get; set; }
}

public class Rate
{
    [XmlAttribute]
    public string Id { get; set; }
    [XmlAttribute]
    public string Name { get; set; }
    [XmlAttribute]
    public string Sector { get; set; }
    [XmlAttribute]
    public string Metering { get; set; }

    [XmlAttribute]
    public string IsDefault { get; set; }
    [XmlAttribute]
    public string IsTimeOfUse { get; set; }
}

Methods to de- and serialize:

    public static void Serialize(string filename, UtilityRateSummaries objToXMl)
    {
        var xs
            = new XmlSerializer(objToXMl.GetType());
        var writer = File.CreateText(filename);
        xs.Serialize(writer, objToXMl);
        writer.Flush();
        writer.Close();
    }

    public static UtilityRateSummaries Deserialize(string filename)
    {

        var xs
            = new XmlSerializer(
                typeof(UtilityRateSummaries));
        var reader = File.OpenText(filename);
        var utilityRateSummaries = (UtilityRateSummaries)xs.Deserialize(reader);
        reader.Close();
        return utilityRateSummaries;
    }

   static void Main(string[] args)
    {
        var obj1 = new UtilityRateSummaries();
        obj1.Utility = new Utility();
        obj1.Utility.UtilityId = 81;
        obj1.Utility.UtilityName = "Pacific Gas and Electric Company (PG&E)";
        obj1.Rate = new Rate();
        obj1.Rate.Id = 238;
        obj1.Rate.Name = "Residential Service (Rate E1 Area Y Code B)";
        obj1.Rate.IsDefault = true;
        obj1.Rate.IsTimeOfUse = false;
        obj1.Rate.Metering = "OptionalNetMetering";
        obj1.Rate.Name = "1";
        obj1.Rate.Sector = "Residential";

        Serialize("bla.xml",obj1);

        var obj = Deserialize("bla.xml");
        Console.Out.WriteLine(obj.Rate.Id);
    }

PS: Your XML is not valid, could be also a problem!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.