Home > Net >  Reading xml nodes into array and getting max value vb.net
Reading xml nodes into array and getting max value vb.net

Time:11-25

I have an xml file like this:

<?xml version="1.0" standalone="yes"?>
<!--This is a V6 File.-->
<ROOT>
  <EVENT>
    <APPOINT.APPNO>123456</APPOINT.APPNO>
    <APPOINT.DATE>01/01/2021</APPOINT.DATE>
    <PERSON_INFO>
      <PERSON.CUSTNO>12131415</PERSON.CUSTNO>
      <PERSON.LAST>WAYNE</PERSON.LAST>
      <PERSON.FIRST>BRUCE</PERSON.FIRST>
      <PERSON.MI />
      <PERSON.STREET>1234 RANDOM ST</PERSON.STREET>
      <PERSON.APT />
      <PERSON.CITY>GOTHAM</PERSON.CITY>
    </PERSON_INFO>
    <ACCOUNT_INFO>
      <CARRIER_ACCOUNT_SUMMARY>
        <ITEM.GROUP>PERSON GROUP</ITEM.GROUP>
        <ITEM.SUM_CHRG>100.50</ITEM.SUM_CHRG>
        <ITEM.SUM_PAID>0</ITEM.SUM_PAID>
        <ITEM.SUM_WOFF>0</ITEM.SUM_WOFF>
        <ITEM.SUM_XOVR>0</ITEM.SUM_XOVR>
        <ITEM.SUM_DEDUCTIBLE>0</ITEM.SUM_DEDUCTIBLE>
        <ITEM.SUM_DUE>100.50</ITEM.SUM_DUE>
      </CARRIER_ACCOUNT_SUMMARY>
      <CARRIER_ACCOUNT_SUMMARY>
        <ITEM.GROUP>PERSON GROUP #2</ITEM.GROUP>
        <ITEM.SUM_CHRG>225.50</ITEM.SUM_CHRG>
        <ITEM.SUM_PAID>110.50</ITEM.SUM_PAID>
        <ITEM.SUM_WOFF>0</ITEM.SUM_WOFF>
        <ITEM.SUM_XOVR>115.00</ITEM.SUM_XOVR>
        <ITEM.SUM_DEDUCTIBLE>0</ITEM.SUM_DEDUCTIBLE>
        <ITEM.SUM_DUE>0.00</ITEM.SUM_DUE>
      </CARRIER_ACCOUNT_SUMMARY>
      <ITEM>
        <ITEM.TRCNO>654321</ITEM.TRCNO>
        <ITEM.INVOICE>987654</ITEM.INVOICE>
      </ITEM>
    </ACCOUNT_INFO>
    <DETAIL_INFO>
      <DETAIL>
        <TOADD.TOANO>123456</TOADD.TOANO>
        <TOADD.EPCRNUM>00-00-000000</TOADD.EPCRNUM>
      </DETAIL>
    </DETAIL_INFO>
  </EVENT>
</ROOT>

I'm getting the nodes I need using this:

Dim xnlNodes As XmlNodeList = xmlDoc.DocumentElement.SelectNodes("/ROOT/EVENT")

I'm trying to get the <ITEM.SUM_CHRG> into an array, so for person.custno'12131415' there would be a value of "100.50", and a value of "225.50" in the array, and I want to use a max method to determine which is the largest value in the array.

I am struggling with just creating the array because I honestly just struggle with arrays in vb.net. I've tried doing a loop, checking the child node names for "ITEM.SUM_CHRG" And putting the value into a variable called strSumChrg so I can check if it's larger that way but I think I'm way off.

I am doing the above inside a for each loop like below

xmlDoc.Load(strFileName)
Dim xnlNodes As XmlNodeList = xmlDoc.DocumentElement.SelectNodes("/ROOT/EVENT")
  For Each xnNode As XmlNode In xnlNodes

        Dim strSumChrg As Decimal = 0
        If xnSC.Name = "ITEM.SUM_CHRG" Then
            If xnSC.FirstChild.Value > 0 Then
                strSumChrg = Math.Max(CDec(xnSC.FirstChild.Value), strSumChrg)
            End If
        End If

Next

CodePudding user response:

Please try the following solution.

It is using LINQ to XML. No loops.

I had to fix the XML file to make it well-formed.

The following tag is not matching in the XML sample.

<ITEM.GROUP>PERSON GROUP</ITEM.GROUP_CARRIER>

VB.NET

Private Sub Main()
    Const fileName As String = "e:\Temp\shadow2020.xml"

    Dim doc As XDocument = XDocument.Load(fileName)
    Dim maxValue = doc.Descendants("ITEM.SUM_CHRG").Max(Function(x) CDec(x))
    Console.WriteLine(maxValue)
End Sub

Output

225.50

CodePudding user response:

You can use XmlSerialization. Create some classes which represent your data

<XmlRoot("ROOT")>
Public Class Root
    <XmlElement("EVENT")>
    Public Property Events As List(Of [Event])
End Class
Public Class [Event]
    <XmlElement("APPOINT.APPNO")>
    Public Property AppointAppNo As Integer
    <XmlElement("APPOINT.DATE")>
    Public Property AppointDateString As String
    <XmlIgnore>
    Public ReadOnly Property AppointDate As DateTime
        Get
            Return DateTime.ParseExact(AppointDateString, "dd/MM/yyyy", Nothing)
        End Get
    End Property
    <XmlElement("PERSON_INFO")>
    Public Property PersonInfo As PersonInfo
    <XmlElement("ACCOUNT_INFO")>
    Public Property AccountInfo As AccountInfo
    <XmlElement("DETAIL_INFO")>
    Public Property DetailInfo As DetailInfo
End Class
Public Class PersonInfo
    <XmlElement("PERSON.CUSTNO")>
    Public Property CustNo As Integer
    <XmlElement("PERSON.LAST")>
    Public Property Last As String
    <XmlElement("PERSON.FIRST")>
    Public Property First As String
    <XmlElement("PERSON.MI")>
    Public Property MI As String
    <XmlElement("PERSON.STREET")>
    Public Property Street As String
    <XmlElement("PERSON.APT")>
    Public Property Apt As String
    <XmlElement("PERSON.CITY")>
    Public Property City As String
End Class
Public Class AccountInfo
    <XmlElement("CARRIER_ACCOUNT_SUMMARY")>
    Public Property Summaries As List(Of Summary)
    <XmlElement("ITEM")>
    Public Property Item As Item
End Class
Public Class DetailInfo
    <XmlElement("DETAIL")>
    Public Property Detail As Detail
End Class
Public Class Summary
    <XmlElement("ITEM.GROUP")>
    Public Property Group As String
    <XmlElement("ITEM.SUM_CHRG")>
    Public Property SumCharge As Decimal
    <XmlElement("ITEM.SUM_PAID")>
    Public Property SumPaid As Decimal
    <XmlElement("ITEM.SUM_WOFF")>
    Public Property SumWoff As Decimal
    <XmlElement("ITEM.SUM_XOVR")>
    Public Property SumXovr As Decimal
    <XmlElement("ITEM.SUM_DEDUCTIBLE")>
    Public Property SumDeductible As Decimal
    <XmlElement("ITEM.SUM_DUE")>
    Public Property SumDue As Decimal
End Class
Public Class Item
    <XmlElement("ITEM.TRCNO")>
    Public Property ItemTrcNo As Integer
    <XmlElement("ITEM.INVOICE")>
    Public Property ItemInvoice As Integer
End Class
Public Class Detail
    <XmlElement("TOADD.TOANO")>
    Public Property ToAddToANo As Integer
    <XmlElement("TOADD.EPCRNUM")>
    Public Property ToAddEpcrNum As String
End Class

Then you can deserialize the file into .NET objects which have strong types and you can iterate using LINQ.

Dim myRoot As Root
Dim serializer As New XmlSerializer(GetType(Root))
Using sr As New StreamReader("list.xml")
    myObject = serializer.Deserialize(sr)
End Using

Dim charges = myRoot.Events.
    Where(Function(e) e.PersonInfo.CustNo = 12131415).
    SelectMany(Function(e) e.AccountInfo.Summaries).
    Select(Function(s) s.SumCharge)

Console.WriteLine("Charges:")
For Each charge In charges
    Console.WriteLine(charge)
Next
Console.WriteLine($"Max: {charges.Max()}")

Charges:
100.50
225.50
Max: 225.50

and of course can do a lot of other things once you have your data in proper .NET objects.

  • Related