0

There is a sp which returns over 300 rows and one of the column has values in FOR XML PATH format. Other columns have normal values.

<row>
  <DocType>1</DocType>
  <GeneralName>CV</GeneralName>
  <StartDate>1900-12-31</StartDate>
  <EndDate>1900-12-31</EndDate>
  <CertNo></CertNo>
</row>

How can I read the values of following elements in .Net and assign them to variables or objects.

<DocType>
<GeneralName>
<StartDate>
<EndDate>
<CertNo>

ADDED

I have tried the following code which seems okay.

         Dim doc As New XmlDocument()
    doc.LoadXml(xmlString)
    Dim DocType As XmlNode = doc.SelectSingleNode("/row/DocType")
    If Not (DocType Is Nothing) Then
        Dim nr As New XmlNodeReader(DocType)
        While nr.Read()
            MsgBox(nr.ReadInnerXml)
        End While
    End If

Is there any other way of doing it efficiently?

Ondrej Svejdar
  • 21,349
  • 5
  • 54
  • 89
user1263981
  • 2,953
  • 8
  • 57
  • 98
  • Please define _efficiently_: is this not running fast enough? What other ways of reading XML in .NET have you found and evaluated? – CodeCaster Nov 18 '13 at 12:59
  • Main concern is the amount rows i will have to loop through and create a new XMLDocument object. There won't be more than 600 rows. I have also come across LINQ to XML. – user1263981 Nov 18 '13 at 13:10

2 Answers2

0

Update - I just realised that the tags have changed to vb.net but the framework classes are the same so I hope it remains useful.

You could use XDocument

//assuming that xml contains the string result XML:
    void Main()
    {
        var xml = GoGetSomeXML();//your sp call here, etc.
        var xd = XDocument.Parse(xml);
        foreach (var row in xd.Descendants().Where(x=>x.Name.LocalName=="row"))
        {
           var DocType = GetSubElementValue(row,"DocType");
           var GeneralName = GetSubElementValue(row,"GeneralName");
           var StartDate = GetSubElementValue(row,"StartDate");
           var EndDate = GetSubElementValue(row,"EndDate");
           var CertNo = GetSubElementValue(row,"CertNo");
           Console.WriteLine("{0} {1} {2} {3} {4}",DocType,GeneralName,StartDate,EndDate,CertNo);
        }
    }

    object GetSubElementValue(XElement container, string subElementName)
    {
       var subElement = container.Descendants().FirstOrDefault(d=>d.Name.LocalName==subElementName);
      if (subElement==null) return null;
      return subElement.Value;
    }

produces

1 CV 1900-12-31 1900-12-31 

Also if your result set is likely to not change and you can control fully the data types, etc, you might also consider using XmlSerializer and define a class that represents the various elements in your result set:

void Main()
{
    var xd = XDocument.Parse(xml);
    var ser =new XmlSerializer(typeof(row));    
    foreach (var rowElement in xd.Descendants().Where(x=>x.Name.LocalName=="row"))
    {
     using (var reader = rowElement.CreateReader())
     {
       var row1 = ser.Deserialize(reader) as row;
       Console.WriteLine(row1);
      }
    }
}


public class row
{
  public int DocType {get;set;}
  public string GeneralName{get;set;}
  public DateTime StartDate{get;set;}
  public DateTime EndDate{get;set;}
  public string CertNo{get;set;}
}

Note that you can use various attributes to control how the XML maps to the ClassName and Properties, so this is a very very basic example - the class name does not have to be "row" when you use the XmlRootAttribute class and so on...

The Serialiser route is probably the most efficient for large amounts of data, although for 300 rows I am not sure you will see much difference.

Stephen Byrne
  • 7,400
  • 1
  • 31
  • 51
  • Thanks, Tried first example and it works great. Do you think this approach is better than XML Parse (XMLReader) http://msdn.microsoft.com/en-us/library/cc189056%28v=vs.95%29.aspx – user1263981 Nov 18 '13 at 14:32
  • came across this link; http://stackoverflow.com/questions/1505075/deciding-on-when-to-use-xmldocument-vs-xmlreader – user1263981 Nov 18 '13 at 14:39
  • *Personally*, I do because I find the Linq-To-XML syntax more "natural" and easier to learn - if you're new to XML Parsing then you can't go wrong with it IMHO. The link you have there is a good one. The serialization approach is going to be the fastest though but in your case it really depends on how much data you have to deal with as well as how comfortable the different APIs are to you! – Stephen Byrne Nov 18 '13 at 14:43
0

You might be able to quickly turn the XML data into a dataset:

Imports System.Xml
...
Public Function GetXMLDataset(XMLText As String) As DataSet
    Try
        Dim ds As New DataSet
        Dim xd As New XmlDocument
        xd.LoadXml(XMLText)
        ds.ReadXml(New XmlNodeReader(xd), XmlReadMode.InferSchema)
        Return ds
    Catch ex As Exception
        MsgBox(ex.Message)
        Return Nothing
    End Try
End Function
rheitzman
  • 2,247
  • 3
  • 20
  • 36