Come sommare il valore decimale da una colonna in una tabella in un file html per C #

c# html-agility-pack html-parsing linq

Domanda

Questo codice intende sommare una colonna di valori decimali ma genera un'eccezione nella int.Parse() . Si prega di vedere vicino alla fine di questo post per come ho provato a rivedere il codice per correggere questo e l'errore che ho ricevuto con quel tentativo.

    static void Main()
    {
        String htmlFile = "C:/Temp/Test11.html";

        HtmlDocument doc = new HtmlDocument();
        doc.Load(htmlFile);

    // Site Collection Storage Used (GB)
    var sum = doc.DocumentNode.SelectSingleNode("//table")
        // The sum will be of the row elements
        .Elements("tr")
        // Skip this many rows from the top
        .Skip(1)
        // .ElementAt(2) = third column
        // .Last() = last column
        .Sum(tr => int.Parse(tr.Elements("td").ElementAt(3).InnerText)); 
    Console.WriteLine("Site Collection Storage Used (GB): " + sum);
        Console.ReadLine();
    }

Ecco l'eccezione:

System.FormatException was unhandled
  HResult=-2146233033
  Message=Input string was not in a correct format.
  Source=mscorlib
  StackTrace:
       at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean     parseDecimal)
       at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
       at System.Int32.Parse(String s)
       at ValueSpecifiedCellSpecifiedTable.Program.<Main>b__2(HtmlNode tr) in c:\Users\User1\Documents\Visual Studio     2012\Projects\_ValueSpecifiedCellSpecifiedTable\ValueSpecifiedCellSpecifiedTable\Program.cs:line 92
       at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
       at System.Linq.Enumerable.Sum(IEnumerable`1 source)
       at System.Linq.Enumerable.Sum[TSource](IEnumerable`1 source, Func`2 selector)
       at ValueSpecifiedCellSpecifiedTable.Program.Main() in c:\Users\User1\Documents\Visual Studio 2012\Projects    \_ValueSpecifiedCellSpecifiedTable\ValueSpecifiedCellSpecifiedTable\Program.cs:line 85
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state,     Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean     preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

Ho provato a sostituire int.Parse () con Decimal.Parse () ma mi dice:

"Error  1   Cannot implicitly convert type 'decimal' to 'int'. An explicit conversion exists (are you missing a cast?)      C:\Users\hptSetupAdmin\Documents\Visual Studio 2012\Projects\_ValueSpecifiedCellSpecifiedTable\ValueSpecifiedCellSpecifiedTable    \Program.cs  92  17  ValueSpecifiedCellSpecifiedTable

Dopo aver cambiato int.Parse() in Decimal.Parse() non vedo dove c'è un int da convertire.

Per favore aiutami con questo codice per raggiungere il mio obiettivo.

Ecco il file html per riferimento:

<html>
<head>
<title>Tables</title>
</head>
<body>
<table border="1">
  <tr>
    <th>Environment</th>
    <th>Databases</th>
    <th>Sites</th>
    <th>Site Collection Storage Used (GB)</th>
    <th>Ref</th>
 </th>
  </tr>
  <tr>
    <td>Public</td>
    <td>14</td>
    <td>28</td>
    <td>32.6602</td>
    <td>2</td>
  </tr>
  <tr>
    <td>Local</td>
    <td>5</td>
    <td>8</td>
    <td>7.0302</td>
    <td>3</td>
  </tr>
  <tr>
    <td>Shared</td>
    <td>6</td>
    <td>9</td>
    <td>17.092</td>
    <td>9</td>
  </tr>
</table>

Risposta accettata

La conversione è quasi certamente al di fuori dell'istruzione LINQ: se sum è un int, è qui che sarebbe necessario un cast esplicito. Dichiarare la somma come decimale o inserire un cast esplicito risolverebbe il problema:

    // Site Collection Storage Used (GB)
    sum = (int)doc.DocumentNode.SelectSingleNode("//table")
        // The sum will be of the row elements
        .Elements("tr")
        // Skip this many rows from the top
        .Skip(1)
        // .ElementAt(2) = third column
        // .Last() = last column
        .Sum(tr => decimal.Parse(tr.Elements("td").ElementAt(3).InnerText)); 
    Console.WriteLine("Site Collection Storage Used (GB): " + sum);

Ecco un link a una demo rapida su ideone (non è possibile utilizzare il pacchetto agility HTML su ideone, quindi ho copiato i tuoi dati in una serie di stringhe).



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché