vb.net: Get data from Xelement <table></table> - vb.net

I have loaded a Xelement from my SharePoint site.
Dim elTable2 As XElement = <table border="1" id="table2" style="font-size:1em;border-collapse:collapse;display:inline;width:100%">
<tbody>
<tr class="ms-rteTableHeaderRow-default" style="text-align:center">
<th class="ms-rteTableHeaderFirstCol-default">​</th>
<th class="ms-rteTableHeaderOddCol-default">LAN IP​</th>
<th class="ms-rteTableHeaderEvenCol-default">Username​</th>
<th class="ms-rteTableHeaderOddCol-default">Password​</th>
<th class="ms-rteTableHeaderEvenCol-default">Port​</th>
<th class="ms-rteTableHeaderOddCol-default">OS​</th>
<th class="ms-rteTableHeaderEvenCol-default">Extra Info​</th>
</tr>
<tr class="ms-rteTableOddRow-default" style="text-align:center">
<th class="ms-rteTableFirstCol-default">Netasq</th>
<td class="ms-rteTableOddCol-default"></td>
<td class="ms-rteTableEvenCol-default"></td>
<td class="ms-rteTableOddCol-default">​</td>
<td class="ms-rteTableEvenCol-default">​</td>
<td class="ms-rteTableOddCol-default">​</td>
<td class="ms-rteTableEvenCol-default">​</td>
</tr>
</tbody>
</table>
The table will have an unknown number of rows. Can I loop trough all the rows and check what data is in the first column?

You could leverage Html Agility Pack for that purpose. It is a .NET code library that allows to parse HTML content and supports plain XPATH or XSLT.
Example
Dim table As XElement = <table border="1" id="table2" style="font-size:1em;border-collapse:collapse;display:inline;width:100%">
<tbody>
<tr class="ms-rteTableHeaderRow-default" style="text-align:center">
<th class="ms-rteTableHeaderFirstCol-default">​Val</th>
<th class="ms-rteTableHeaderOddCol-default">LAN IP​</th>
<th class="ms-rteTableHeaderEvenCol-default">Username​</th>
<th class="ms-rteTableHeaderOddCol-default">Password​</th>
<th class="ms-rteTableHeaderEvenCol-default">Port​</th>
<th class="ms-rteTableHeaderOddCol-default">OS​</th>
<th class="ms-rteTableHeaderEvenCol-default">Extra Info​</th>
</tr>
<tr class="ms-rteTableOddRow-default" style="text-align:center">
<td class="ms-rteTableFirstCol-default">Netasq</td>
<td class="ms-rteTableOddCol-default"></td>
<td class="ms-rteTableEvenCol-default"></td>
<td class="ms-rteTableOddCol-default">​</td>
<td class="ms-rteTableEvenCol-default">​</td>
<td class="ms-rteTableOddCol-default">​</td>
<td class="ms-rteTableEvenCol-default">​</td>
</tr>
</tbody>
</table>
Dim html = New HtmlDocument()
html.LoadHtml(table.ToString())
For Each row In html.DocumentNode.SelectNodes("//tr[position()>1]") 'XPath expression to select table rows and skip table header
Dim cell As HtmlNode = row.SelectSingleNode("td[1]") 'Get cell for first column
Console.WriteLine(cell.InnerText)
Next

Related

WebSupergoo.ABCpdf10 exception "Illegal characters in path"

I am trying to re-build an old .NET Visual Basic application I have inherited that uses WebSupergoo.ABCpdf10 (ABCpdf, Version=10.1.2.5). I am getting an exception "Illegal characters in path", ultimately thrown by the method System.IO.Path.CheckInvalidPathChars. However, this is called by the external code, so I have little control over it. The stack trace is as follows:
[ArgumentException: Illegal characters in path.]
System.IO.Path.CheckInvalidPathChars(String path, Boolean checkAdditional) +12831187
System.IO.Path.Combine(String path1, String path2) +34
WebSupergoo.ABCpdf10.Internal.Gecko.GeckoRpc.GetABCGeckoPath(String currLoc, String installDir) +378
WebSupergoo.ABCpdf10.Internal.Gecko.WorkerPool.AddRef(HtmlManagedOptions managedOptions) +332
WebSupergoo.ABCpdf10.Internal.Gecko.AddUrlProgress.Start(Boolean readAsync) +91
WebSupergoo.ABCpdf10.Internal.Gecko.DocAddGecko.AddUrl(String url) +1260
WebSupergoo.ABCpdf10.Internal.Gecko.DocAddGecko.AddHtml(String html) +290
WebSupergoo.ABCpdf10.Doc.AddUrlHtml(String urlOrHtml, Boolean isHtml, Boolean paged, Int32 width, Boolean disableCache) +251
WebSupergoo.ABCpdf10.Doc.AddImageHtml(String html, Boolean paged, Int32 width, Boolean disableCache) +49
GI.Platform.Core.Business.PdfDocument.AddHtml(String html, Int32 browserWidth, PageOrientation pageOrientation, Boolean paged) in C:\Users\MartinVaughan\Documents\Development\GI Platform\original-platform\GI.Platform.Core\Business\PDFDocument.vb:168
GI.Platform.UI.Legacy.UserControls.Admin.ReportGeneration.btnGPIBasicReportPdf_Click(Object sender, EventArgs e) in C:\Users\MartinVaughan\Documents\Development\GI Platform\original-platform\GI.Platform.UI\UserControls\Admin\ManageRegistration\ReportGeneration.ascx.vb:234
System.Web.UI.WebControls.LinkButton.OnClick(EventArgs e) +121
System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +108
System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +12
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +15
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +9859004
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1696
The method GI.Platform.Core.Business.PdfDocument.AddHtml is ours and passes an HTML-formatted string. Thereafter, the methods are external (part of the WebSupergoo package). Our method calls AddImageHtml, which appears to call AddUrlHtml.
I have stripped all URLs out of the HTML string (as I thought this might be the problem). I have also stripped out any characters I thought might be dubious. The HTML string is now (indentation added here for readability):
<html>
<head>
</head>
<body>
<table cellpadding='5' cellspacing='0' border='0' width='100%'>
<tr>
<td rowspan='3' width='350'></td>
<td class='titleCell'>GPI™ Datasheet</td>
</tr>
<tr>
<td class='nameCell'>User Name</td>
</tr>
<tr>
<td class='dateCell'>Generated on 13/09/2022</td>
</tr>
</table>
<br />
<table cellpadding='0' cellspacing='0' border='0' width='90%' class='data' align='center'>
<tr class='header'>
<th class='centerAlign'>Dimension/Sub-Dimension</th>
<th class='centerAlign'>Type</th>
<th class='centerAlign'>Rank</th>
</tr>
<tr class='dimension'>
<th class='leftAlign'>
<b>Incremental - Radical</b>
</th>
<th class='leftAlign'>
<b>Incremental</b>
</th>
<th class='centerAlign'>
<b>3</b>
</th>
</tr>
<tr>
<td class='leftAlign'>Evolutionary - Revolutionary</td>
<td class='leftAlign'>Evolutionary</td>
<td class='centerAlign'>2</td>
</tr>
<tr>
<td class='leftAlign'>Practical - Conceptual</td>
<td class='leftAlign'>Practical</td>
<td class='centerAlign'>3</td>
</tr>
<tr>
<td class='leftAlign'>Rational - Intuitive</td>
<td class='leftAlign'>Rational</td>
<td class='centerAlign'>4</td>
</tr>
<tr class='dimension'>
<th class='leftAlign'>
<b>Focused - Flexible</b>
</th>
<th class='leftAlign'>
<b>Focused</b>
</th>
<th class='centerAlign'>
<b>4</b>
</th>
</tr>
<tr>
<td class='leftAlign'>Outcome - Spontaneous</td>
<td class='leftAlign'>Outcome</td>
<td class='centerAlign'>4</td>
</tr>
<tr>
<td class='leftAlign'>Conscientious - Cursory</td>
<td class='leftAlign'>Conscientious</td>
<td class='centerAlign'>5</td>
</tr>
<tr>
<td class='leftAlign'>Perfectionist - Pragmatic</td>
<td class='leftAlign'>Perfectionist</td>
<td class='centerAlign'>2</td>
</tr>
<tr class='dimension'>
<th class='leftAlign'>
<b>Extraversion - Introversion</b>
</th>
<th class='leftAlign'>
<b>Introversion</b>
</th>
<th class='centerAlign'>
<b>3</b>
</th>
</tr>
<tr>
<td class='leftAlign'>Outgoing - Reserved</td>
<td class='leftAlign'>Reserved</td>
<td class='centerAlign'>5</td>
</tr>
<tr>
<td class='leftAlign'>Asserting - Accepting</td>
<td class='leftAlign'>Accepting</td>
<td class='centerAlign'>1</td>
</tr>
<tr>
<td class='leftAlign'>Fun Loving - Serious-Minded</td>
<td class='leftAlign'>Serious-Minded</td>
<td class='centerAlign'>5</td>
</tr>
<tr>
<td class='leftAlign'>Socially Assured - Socially Uncertain</td>
<td class='leftAlign'>Socially Uncertain</td>
<td class='centerAlign'>2</td>
</tr>
<tr class='dimension'>
<th class='leftAlign'>
<b>Collectivist - Individualist</b>
</th>
<th class='leftAlign'>
<b>Individualist</b>
</th>
<th class='centerAlign'>
<b>4</b>
</th>
</tr>
<tr>
<td class='leftAlign'>Affiliative - Unaffiliative</td>
<td class='leftAlign'>Unaffiliative</td>
<td class='centerAlign'>5</td>
</tr>
<tr>
<td class='leftAlign'>Trusting - Questioning</td>
<td class='leftAlign'>Questioning</td>
<td class='centerAlign'>3</td>
</tr>
<tr>
<td class='leftAlign'>Conforming - Dissenting</td>
<td class='leftAlign'>Dissenting</td>
<td class='centerAlign'>5</td>
</tr>
<tr>
<td class='leftAlign'>Modest - Assuming</td>
<td class='leftAlign'>Assuming</td>
<td class='centerAlign'>3</td>
</tr>
<tr class='dimension'>
<th class='leftAlign'>
<b>At Ease - Ill-at Ease</b>
</th>
<th class='leftAlign'>
<b>Ill-at Ease</b>
</th>
<th class='centerAlign'>
<b>2</b>
</th>
</tr>
<tr>
<td class='leftAlign'>Relaxed - Tense</td>
<td class='leftAlign'>Tense</td>
<td class='centerAlign'>1</td>
</tr>
<tr>
<td class='leftAlign'>Placid - Discontented</td>
<td class='leftAlign'>Discontented</td>
<td class='centerAlign'>5</td>
</tr>
<tr>
<td class='leftAlign'>Optimistic - Pessimistic</td>
<td class='leftAlign'>Pessimistic</td>
<td class='centerAlign'>3</td>
</tr>
<tr>
<td class='leftAlign'>Confident - Self-Conscious</td>
<td class='leftAlign'>Confident</td>
<td class='centerAlign'>1</td>
</tr>
<tr class='dimension'>
<th class='leftAlign'>
<b>Disciplined - Impulsive</b>
</th>
<th class='leftAlign'>
<b>Disciplined</b>
</th>
<th class='centerAlign'>
<b>3</b>
</th>
</tr>
<tr class='dimension'>
<th class='leftAlign'>
<b>Driving - Measured</b>
</th>
<th class='leftAlign'>
<b>Measured</b>
</th>
<th class='centerAlign'>
<b>1</b>
</th>
</tr>
<tr>
<td class='leftAlign'>Persuasive - Consensual</td>
<td class='leftAlign'>Consensual</td>
<td class='centerAlign'>1</td>
</tr>
<tr>
<td class='leftAlign'>Ambitious - Contented</td>
<td class='leftAlign'>Ambitious</td>
<td class='centerAlign'>2</td>
</tr>
<tr>
<td class='leftAlign'>Energetic - Paced</td>
<td class='leftAlign'>Paced</td>
<td class='centerAlign'>3</td>
</tr>
</table>
<br />
<table cellpadding='0' cellspacing='0' border='0' align='center'>
<tr>
<td class='copyrightCell'>© 2022 Glowinkowski International Limited</td>
</tr>
</table>
</body>
</html>
(Note: I have removed the link to the CSS file and an image with a URL, as I thought these might be creating the problem).
Still getting the exception!
Could anyone throw any light on this?
Edit
Looking at the WebSupergoo documentation at https://www.websupergoo.com/helppdfnet/default.htm?page=source%2f5-abcpdf%2fdoc%2f1-methods%2faddimagehtml.htm they note that:
Using the MSHTML, ABCGecko and ABCWebKit engines, ABCpdf saves this HTML into a temporary file and renders the file using a 'file://' protocol specifier. So this is a convenience function - it doesn't offer any performance enhancements. Sometimes the IIS users do not have full access to the temp directory. This is determined by the system setup you have on your machine. If this is the case you will get errors returned. So if you are working from ASP you may find that you need to enable access to the temp directory for the ASPNET user, the IUSR_MACHINENAME user or the IWAM_MACHINENAME user.
This may be the root cause of the problem, in which case, my question would translate to how do I enable access in my Visual Studio build?.

Simple table with colspan giving errors with datatables

I have this simple html table
<table id="mytable">
<thead>
<tr>
<th>Name</th>
<th colspan="2">Actions</th>
</tr>
<tr>
<th>Delete</th>
<th>Update</th>
</tr>
</thead>
<tbody>
<tr>
<td>MyName</td>
<td onclick="delete()">X</td>
<td onclick="update()">U</td>
</tr>
</tbody>
</table>
<script>
$(document).ready(function(){
$('#mytable').DataTable();
});
</script>
If i open this on the browser i get
"Cannot read property 'mData' of undefined".
I don't undestand where is the problem.. I am following the official example: https://datatables.net/examples/basic_init/complex_header.html
Thank you all!
your html have unmatched number of columns, notice the first row of your header has colspan while the second row doesn't.
what you can do is to provide a rowspan.
<thead>
<tr>
<th rowspan="2">Name</th>
<th colspan="2">Actions</th>
</tr>
<tr>
<th>Delete</th>
<th>Update</th>
</tr>
</thead>
here's a link to the datatables example of complex headers. https://datatables.net/examples/basic_init/complex_header.html

Finding Duplicate Pairs in Excel

So I have this summary sheet. It contains data from multiple workbooks going across.
It's not like this question, because what I'm trying to do is find all the inconsistant pairs of data in this worksheet going across and highlight them.
Here is a fiddle that explains what I want to accomplish. I have a large worksheet, and would like to compare the first 2 rows with the next 2 rows etc. throughout the worksheet. Below is an HTML representation of what I am trying to accomplish.
<table class="tg">
<tr>
<th class="tg-031e">#INT1</th>
<th class="tg-031e">#INT1</th>
<th class="tg-031e">#INT2</th>
<th class="tg-031e">#INT2</th>
<th class="tg-031e">#INT3</th>
<th class="tg-031e">#INT3</th>
</tr>
<tr>
<td class="tg-031e">Apples</td>
<td class="tg-031e">Y</td>
<td class="tg-031e">Bananas</td>
<td class="tg-031e">Y</td>
<td class="tg-031e">Apples</td>
<td class="tg-031e">Y</td>
</tr>
<tr>
<td class="tg-031e">Bananas</td>
<td class="tg-031e">Y</td>
<td class="tg-031e">Peppers</td>
<td class="tg-031e">Y</td>
<td class="tg-031e">Bananas</td>
<td class="tg-031e">Y</td>
</tr>
<tr>
<td class="tg-031e">Peppers</td>
<td class="tg-031e">Y</td>
<td class="tg-031e">Pomegranite</td>
<td class="tg-031e">Y</td>
<td class="tg-031e">Peppers</td>
<td class="tg-031e">Y</td>
</tr>
<tr>
<td class="tg-031e">Pomegranite</td>
<td class="tg-031e">Y</td>
<td class="tg-031e">Nuts</td>
<td class="tg-031e">YYYYYNN</td>
<td class="tg-031e">Pomegranite</td>
<td class="tg-031e">Y</td>
</tr>
<tr>
<td class="tg-031e">Nuts</td>
<td class="tg-031e">YYYYYYNN</td>
<td class="tg-031e">Smango</td>
<td class="tg-031e">NNNYYNNN</td>
<td class="tg-031e">Nuts</td>
<td class="tg-031e">NNNYNNNN</td>
</tr>
<tr>
<td class="tg-zl7m">Oranges</td>
<td class="tg-zl7m">YYYYNNNN</td> <!-- this oranges is different from... -->
<td class="tg-031e">Blackberries</td>
<td class="tg-031e">NNNYYNNNN</td>
<td class="tg-zl7m">Oranges</td>
<td class="tg-zl7m">NNNYYNNN</td> <!-- ...this one -->
</tr>
<tr>
<td class="tg-031e">Smango</td>
<td class="tg-031e">NNNYYNNN</td>
<td class="tg-031e">Berries</td>
<td class="tg-031e">YYNYNNNN</td>
<td class="tg-031e">Smango</td>
<td class="tg-031e">Y</td>
</tr>
<tr>
<td class="tg-031e">Skiwi</td>
<td class="tg-031e">NNNYNNNN</td>
<td class="tg-031e">Beer</td>
<td class="tg-031e">NNNYNNNN</td>
<td class="tg-031e">Steaks</td>
<td class="tg-031e">Y</td>
</tr>
<tr>
<td class="tg-031e">Steaks</td>
<td class="tg-031e">Y</td>
<td class="tg-031e">Blueberries</td>
<td class="tg-031e">YNNYNNNN</td>
<td class="tg-031e">Steaksauce</td>
<td class="tg-031e">NNNYNNNN</td>
</tr>
<tr>
<td class="tg-zl7m">Steaksauce</td>
<td class="tg-zl7m">YYNYNNNN</td>
<td class="tg-031e">Blucheese</td>
<td class="tg-031e">NNNYNNNN</td>
<td class="tg-zl7m">Apricot</td>
<td class="tg-zl7m">YYYYNNNN</td>
</tr>
<tr>
<td class="tg-031e">Apricot</td>
<td class="tg-031e">YYYYNNNN</td>
<td class="tg-031e">Blackberries</td>
<td class="tg-031e">NNNYNNNN</td>
<td class="tg-031e">Milkshake</td>
<td class="tg-031e">NNNYNNNN</td>
</tr>
</table>
I have tried VBA solutions and also conditional formatting. Any solution that will make this work is greatly appreciated.
Thank you.
I think this array formula should work:-
=SUM(ISODD(COLUMN())*($A$2:$E$12=A2)*($B$2:$F$12<>B2))
if the table starts in A1, this can be applied as conditional formatting from A2 to E12 and will highlight the left-hand (fruit) cell of inconsistent pair of cells.
Then you can use a similar formula to highlight the right-hand cell of each pair:-
=SUM(ISEVEN(COLUMN())*($A$2:$E$12=A2)*($B$2:$F$12<>B2))
Apply this from B2 to F12.
Note that Smango are highlighted because they are in an inconsistent group (although they are also in a consistent group).
Here is the alternative approach (as suggested) of highlighting the consistent groups:-
The formulae are
=SUM(ISODD(COLUMN())*($A$2:$E$12=A2)*($B$2:$F$12=B2))>1
and
=SUM(ISEVEN(COLUMN())*($A$2:$E$12=A2)*($B$2:$F$12=B2))>1
to be applied as before.
The sum this time will always be at least one because each pair of cells will match with itself, so the '>' sign is to find if there are any matches with other pairs of cells.

<td style='text-align: right'> incorrectly aligned in IE11

I am trying to right align the values, but those are not aligning properly to the end of the column.
Example code:
<table id="demoTable1" cellspacing="0" cellpadding="0" border="1">
<thead>
<tr>
<th style="text-align:right; width:23%"><bean:message key="label.amount"/></th>
</tr>
</thead>
<tbody >
<c:forEach items="${demoForm.amount}" var="amt" >
<tr>
<td dntitle="myAmt" style="text-align:right; width:23%">
<util:myCurrency name="amt" property="amtList" currProperty="curCode"/>
</td>
</tr>
</c:forEach>
</tbody>
</table>
And the Output looks like this:
How can I fix this?

Selenium - pulling data from a website table assign to variable

I am attempting to pull a value and a header (string) from a website, but unable to find the element using selenium.
My Code
I used Firebug to get the XPath and this is what it determined:
//*[#id="DimensionForm"]/p[1]/table/tbody/tr[3]/td[3]
Code
Dim Right as double
Dim Marker as string
Marker = selenium.findElementByXPath("//*[#id="DimensionForm"]/p[1]/table/tbody/tr[2]/td[3]").getAttribute("value")
Right = selenium.findElementByXPath("//*[#id="DimensionForm"]/p[1]/table/tbody/tr[3]/td[3]").getAttribute("value")
HTML CODE
<form id="DimensionForm" name="validate" action="Dimension" method="post">
<div style="margin-top: 7px"></div>
<p><table width="100%" cellspacing="0" border="0" cellpadding="0" class="element">
<tr>
<td> </td><td class="formtitlenobg" colspan="6" align='right'>
AREA DIMENSIONS (AREA A) <span class='quote'> Front</span> 25.24</td>
</tr>
<tr align="right">
<td class="tablerowlightgreen" width=10> </td>
<th class="formtitle" width=250 align="left">Property</th>
<th class="formtitle" width=50>Check</th> <th class="formtitle" width=75>Front</th>
<th class="formtitle" width=75>Center</th><th class="formtitle" width=75>Left</th>
<th class="formtitle" width=120>Right</th>
<th class="formtitle" width=100>Total</th>
<td class="tablerow" width=50> </td>
<td class="tablerow"> </td>
</tr>
<tr align="right" nowrap>
<td> </td>
<td class="table" align="left"><strong>
Property O</strong></td>
<td class="table">+</td>
<td class="table">10</td>
<td class="table">12</td>
<td class="table"><strong>12</strong></td>
<td class="table"><strong><font class="front">
100</font></strong></td>
<td class="table">120</td>
<td> </td>
<td> </td>
</tr>
</table></td>
</tr></table>
You have incorrectly nested quotes:
selenium.findElementByXPath("//*[#id="DimensionForm"]/p[1]/table/tbody/tr[2]/td[3]")
Perhaps you meant:
selenium.findElementByXPath("//*[#id='DimensionForm']/p[1]/table//tr[2]/td[3]")
Note the single-quotes in the second line!