Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract data from a XML string using linq vs xmlDocument

Tags:

c#

xml

linq

I have done the below many times using a xmlDocument approach, but I wanted to use the more powerful linq to xml approach. However, I seem to have run into a wall. I am getting data back from a restful API from twillio / crmText. Here is a link to their site where their docs live: http://crmtext.com/api/docs

Here is my XML string:

<response op="getcustomerinfo" status="200" message="ok" version="1.0">
  <customer>
    <totalMsg>3</totalMsg>
    <custId>9008281</custId>
    <custName></custName>
    <timestamp>2015-04-30 16:17:19</timestamp>
    <optinStatus>3</optinStatus>
    <custMobile>6185551212</custMobile>
    <subacct>1st Choice Courier</subacct>
  </customer>
</response>

I need to find out the optinStatus. It should return 3. I am using the below, which return the above xml

XDocument xdoc = XDocument.Parse(result1);

I have tried about 4000 different things, including:

 IEnumerable<XElement> otinStatus = from el in xdoc.Elements("customer") select el;
          IEnumerable<XElement> otinStatus2 = from el in xdoc.Elements("cusotmer.optinStatus") select el;
           IEnumerable<XElement> otinStatus3 = from el in xdoc.Elements("optinStatus") select el;

All of which returns no results.

Please help, I know this is something simple I am missing. Thank you in advance -- Joe

like image 416
Joe Ruder Avatar asked May 13 '15 02:05

Joe Ruder


People also ask

Should I use XDocument or XmlDocument?

XDocument is from the LINQ to XML API, and XmlDocument is the standard DOM-style API for XML. If you know DOM well, and don't want to learn LINQ to XML, go with XmlDocument . If you're new to both, check out this page that compares the two, and pick which one you like the looks of better.

Does LINQ work with XML?

The most important advantage of LINQ to XML is its integration with Language-Integrated Query (LINQ). This integration enables you to write queries on the in-memory XML document to retrieve collections of elements and attributes.

Which of the following options is created to retrieve data into XML using LINQ?

The LINQ to XML will bring the XML document into memory and allows us to write LINQ Queries on in-memory XML document to get the XML document elements and attributes. To use LINQ to XML functionality in our applications, we need to add "System. Xml. Linq" namespace reference.


2 Answers

Retrieve an Element's Value

var status = xDoc
    .Descendants("optinStatus")    // get the optinStatus element
    .Single()                      // we're expecting a single result
    .Value;                        // get the XElement's value

Example

Here is a working Fiddle for you. You can see it running live here. The output is 3.

using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

public class Program
{
    public static void Main()
    {
        var xDoc = XDocument.Parse(xmlString);
        var status = xDoc.Descendants("optinStatus").Single();
        Console.WriteLine(status.Value);
    }

    private static string xmlString = @"

<response op=""getcustomerinfo"" status=""200"" message=""ok"" version=""1.0"">
  <customer>
    <totalMsg>3</totalMsg>
    <custId>9008281</custId>
    <custName></custName>
    <timestamp>2015-04-30 16:17:19</timestamp>
    <optinStatus>3</optinStatus>
    <custMobile>6185312349</custMobile>
    <subacct>1st Choice Courier</subacct>
  </customer>
</response> 

    ";
}

Explanation

Descendents() is an instance axes method (or just axes in shorthand). It returns an IEnumerable<XElement> of all matching descendents. On its results, we call Single(). It is a Linq method that returns the only element of a sequence. If there is more than one element, it throws an error. We're left with a single XElement. This represent an entire XML element. Since we only want its value not the entire element, we call the Value property. Bingo, we're done.

A Bit More Detail

Axes come in two kinds:

  • Instance axes methods, which MSDN lists here, are invokable members of the XElement, XDocument, and XNode classes.
  • Extension axes methods, which MSDN lists here, are invokable on collections.

With one exception, an axes method returns a collection of type IEnumerable<T>. The exception is Element(), which returns the first matching child object. That what AmatuerDev used and, as in your question, if you are only expecting a single result, it is a just as good if not better approach that is Descendants().

Retrieve an Attribute Value

Once we have an XElement, we can retrieve one of its attributes instead of its value. We do that by calling the Attributes() method. It returns the matching XAttribute. Since we only want the attribute value, we call the Value property. Voila.

// for attribute
var response = xDoc.Descendants("response").Single();
var attr = response.Attribute("status");

General Approach

Using Linq to XML is a two step process.

  1. Call an axes method to obtain an IEnumerable<T> result.
  2. Use Linq to query that.

See Also

Here is some relevant MSDN documentation:

  • How to: Retrieve the Value of an Element (LINQ to XML)
  • LINQ to XML Axes
like image 111
Shaun Luttin Avatar answered Oct 20 '22 01:10

Shaun Luttin


Assuming xDoc being the XDocument. Have you tried..

  var customer = xDoc.Root.Element("customer");
  var optinStatus = customer.Element("optinStatus");
  var optinStatusValue = optinStatus.Value;
like image 37
Nathan Avatar answered Oct 20 '22 00:10

Nathan