net C#. I am trying to parse Json from a webservice. I have done it with text but having a problem with parsing image. Here is the Url from where I m getting Json
http://collectionking.com/rest/view/items_in_collection.json?args=122
And this is My code to Parse it
using (var wc = new WebClient()) {
JavaScriptSerializer js = new JavaScriptSerializer();
var result = js.Deserialize<ck[]>(wc.DownloadString("http://collectionking.com/rest/view/items_in_collection.json args=122"));
foreach (var i in result) {
lblTitle.Text = i.node_title;
imgCk.ImageUrl = i.["main image"];
lblNid.Text = i.nid;
Any help would be great.
Thanks in advance.
PS: It returns the Title and Nid but not the Image.
My class is as follows:
public class ck
{
public string node_title;
public string main_image;
public string nid; }
Your problem is that you are setting ImageUrl to something like this <img typeof="foaf:Image" src="http://... and not an actual url. You will need to further parse main image and extract the url to show it correctly.
Edit
This was a though nut to crack because of the whitespace. The only solution I could find was to remove the whitespace before parsing the string. It's not a very nice solution but I couldn't find any other way using the built in classes. You might be able to solve it properly using JSON.Net or some other library though.
I also added a regular expression to extract the url for you, though there is no error checking what so ever here so you'll need to add that yourself.
using (var wc = new WebClient()) {
JavaScriptSerializer js = new JavaScriptSerializer();
var result = js.Deserialize<ck[]>(wc.DownloadString("http://collectionking.com/rest/view/items_in_collection.json?args=122").Replace("\"main image\":", "\"main_image\":")); // Replace the name "main image" with "main_image" to deserialize it properly, also fixed missing ? in url
foreach (var i in result) {
lblTitle.Text = i.node_title;
string realImageUrl = Regex.Match(i.main_image, #"src=""(.*?)""").Groups[1].Value; // Extract the value of the src-attribute to get the actual url, will throw an exception if there isn't a src-attribute
imgCk.ImageUrl = realImageUrl;
lblNid.Text = i.nid;
}
}
Try This
private static string ExtractImageFromTag(string tag)
{
int start = tag.IndexOf("src=\""),
end = tag.IndexOf("\"", start + 6);
return tag.Substring(start + 5, end - start - 5);
}
private static string ExtractTitleFromTag(string tag)
{
int start = tag.IndexOf(">"),
end = tag.IndexOf("<", start + 1);
return tag.Substring(start + 1, end - start - 1);
}
It may help
Related
I'm using Ubuntu and dotnet 3.1, running vscode's c# extension.
I need to create a List from a JSON file, my controller will do some calculations with this model List that I will pass to it
So, here is my code and the error I'm getting.
First, I thought my error was because at model my attributes were char and C#, for what I saw, cannot interpret double-quotes for char, it should be single quotes. Before losing time removing it, I just changed my type declarations to strings and it's the same error.
Can someone help me?
ElevadorModel
using System.Collections.Generic;
namespace Bla
{
public class ElevadorModel
{
public int andar { get; set; }
public string elevador { get; set; }
public string turno { get; set; }
}
}
Program.cs:
class Program
{
static void Main(string[] args)
{
var path = "../input.json";
string jsonString;
ElevadorModel elevadoresModel = new ElevadorModel();
jsonString = File.ReadAllText(path); //GetType().Name = String
Console.WriteLine(jsonString); //WORKS
elevadoresModel = JsonSerializer.Deserialize<ElevadorModel>(jsonString);
}
JSON:
Your input json has an array as the base token, whereas you're expecting an object. You need to change your deserialization to an array of objects.
var elevadoresModels = JsonSerializer.Deserialize<List<ElevadorModel>>(jsonString);
elevadoresModel = elavoresModels.First();
Your input JSON is an array of models, however you're trying to deserialize it to a single model.
var models = JsonSerializer.Deserialize<List<ElevadorModel>>(jsonString);
This is also a problem in Blazor-Client side. For those calling a single object
e.g ClassName = await Http.GetFromJsonAsync<ClassName>($"api/ClassName/{id}");
This will fail to Deserialize. Using the same System.Text.Json it can be done by:
List<ClassName> ListName = await Http.GetFromJsonAsync<List<ClassName>>($"api/ClassName/{id}");
You can use an array or a list. For some reason System.Text.Json, does not give errors and it is successfully able Deserialize.
To access your object, knowing that it is a single object use:
ListName[0].Property
In your case the latter solution is fine but with the path as the input.
In my case, I was pulling the JSON data to deserialize out of an HTTP response body. It looked like this:
var resp = await _client.GetAsync($"{endpoint}");
var respBody = await resp.Content.ReadAsStringAsync();
var listOfInstances = JsonSerializer.Deserialize<List<modelType>>(respBody);
And the error would show up. Upon further investigation, I found the respBody string had the JSON base object (an array) wrapped in double quotes...something like this:
"[{\"prop\":\"value\"},...]"
So I added
respBody = respBody.Trim('\"');
And the error changed! Now it was pointing to an invalid character '\'.
I changed that line to include
respBody = respBody.Trim('\"').Replace("\\", "");
and it began to deserialize perfectly.
For reference:
var resp = await _client.GetAsync($"{endpoint}");
var respBody = await resp.Content.ReadAsStringAsync();
respBody = respBody.Trim('\"').Replace("\\", "");
var listOfInstances = JsonSerializer.Deserialize<List<modelType>>(respBody);
public class QuoteGenerator
{
public static randomQuote()
{
string t = "Quotes.txt";
List<string> Quotes = new List<string>();
using (StreamReader quoteReader = new StreamReader(t))
{
string line = "";
while ((line = quoteReader.ReadLine()) != null)
{
Quotes.Add(line);
}
}
string[] response = Quotes.ToArray();
string[] shuffle = Classes.RandomStringArrayTool.RandomizeStrings(response);
return (shuffle[0]);
}
}
Here's what's working and I thought my StreamReader code above would work the same:
public string randomQuote()
{
string[] response = new string[] {"The fortune you seek, is in another bot"
, "Someone has Googled you recently"
, "This fortune no good. Try another"
, "404 fortune not found"};
string[] shuffle = Classes.RandomStringArrayTool.RandomizeStrings(response);
return shuffle[0];
}
I need to return the first line of quote from the StreamReader Method, how come the code I put together doesn't seem to work? I've thought about hard-coding the quotes but maybe it's a good idea to save them in a text file. I guess I don't understand how using StreamReader work. Can anyone please explain, I've only been coding since July. Thank you!
Assuming your Quotes.txt file is in the bin directory the StreamReader code works fine. The only thing obvious is that you are not specifying a return type for the randomQuote method.
public static string randomQuote()
I have a URL and from which i need to get names after "bussiness" and Before the Page Name i.e. "paradise-villas-little.aspx" from below URL.
http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx
I am not getting how can i get this. i have tried the RawUrl, but it fetched the full. Please help me how can i do this.
UPDATE: This is a type of URL, i need to check it for dynamically.
You can create a little helper, and parse the URL from it's Uri Segments :
public static class Helper
{
public static IEnumerable<String> ExtractSegments(this Uri uri, String exclusiveStart)
{
bool startFound = false;
foreach (var seg in uri.Segments.Select(i => i.Replace(#"/","")))
{
if (startFound == false)
{
if (seg == exclusiveStart)
startFound = true;
}
else
{
if (!seg.Contains("."))
yield return seg;
}
}
}
}
And call it like this :
Uri uri = new Uri(#"http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx");
var found = uri.ExtractSegments("bussiness").ToList();
Then found contains "accommo" and "resort", and this method is extensible to any URL length, with or without file name at the end.
Nothing sophisticated in this implementation, just regular string operations:
string url = "http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx";
string startAfter = "business";
string pageName = "paradise-villas-little.aspx";
char delimiter = '/'; //not platform specific
var from = url.IndexOf(startAfter) + startAfter.Length + 1;
var to = url.Length - from - pageName.Length - 1;
var strings = url.Substring(from, to).Split(delimiter);
You may want to add validations though.
You have to use built-in string methods. The best is to use String Split.
String url = "http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx";
String[] url_parts = url.Split('/'); //Now you have all the parts of the URL all folders and page. Access the folder names from string array.
Hope this helps
Question Background:
Update:
I'm still not sure how to go about extracting the relevant information from this response. I have tried setting my response type to JSON but still receive the response as shown below. I have taken into account what has been said in regards to using NameValueCollection but still cant see how this will help with such a large response. Ideally I'd like this mapped to an object structure of some kind, it dosen't necessarily have to be JSON.
Question:
I'm currently using the PayPal Api 'ExpressCheckout' method to allow users to pay for items on my test site. A HTTP response from the API provides a large response containing key information I need to extract - such as the buyers address, if the payment was succesful etc.
The Issue:
Currently I'm stuck on how to work with the response. Ideally I'd convert the data to a JSON string then use Newtonsoft to map the data to C# classes thus allowing easy access to the data. Here is an example of the Httpresponse:
TOKEN=EC%2XXXXXXXXXXXXXXXXXR&BILLINGAGREEMENTACCEPTEDSTATUS=0&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2015%2d01%2d02T21%3a11%3a30Z&CORRELATIONID=ab184fdba7a30&ACK=Success&VERSION=88%2e0&BUILD=14443165&EMAIL=test%40aol%2ecom&PAYERID=3XXXXXXXXXX4N&PAYERSTATUS=verified&BUSINESS=Test%20Biz%27s%20Test%20Store&FIRSTNAME=Joe&LASTNAME=King&COUNTRYCODE=GB&SHIPTONAME=Joe%20King%27s%20Test%20Store&SHIPTOSTREET=1%20Main%20Terrace&SHIPTOCITY=Wolverhampton&SHIPTOSTATE=West%20Midlands&SHIPTOZIP=W12%204LQ&SHIPTOCOUNTRYCODE=GB&SHIPTOCOUNTRYNAME=United%20Kingdom&ADDRESSSTATUS=Confirmed&CURRENCYCODE=GBP&AMT=15%2e56&ITEMAMT=15%2e56&SHIPPINGAMT=0%2e00&HANDLINGAMT=0%2e00&TAXAMT=0%2e00&INSURANCEAMT=0%2e00&SHIPDISCAMT=0%2e00&L_NAME0=ItemOne&L_QTY0=4&L_TAXAMT0=0%2e00&L_AMT0=3%2e89&L_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_ITEMHEIGHTVALUE0=%20%20%200%2e00000&PAYMENTREQUEST_0_CURRENCYCODE=GBP&PAYMENTREQUEST_0_AMT=15%2e56&PAYMENTREQUEST_0_ITEMAMT=15%2e56&PAYMENTREQUEST_0_SHIPPINGAMT=0%2e00&PAYMENTREQUEST_0_HANDLINGAMT=0%2e00&PAYMENTREQUEST_0_TAXAMT=0%2e00&PAYMENTREQUEST_0_INSURANCEAMT=0%2e00&PAYMENTREQUEST_0_SHIPDISCAMT=0%2e00&PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&PAYMENTREQUEST_0_SHIPTONAME=Joe%20King%27s%20Test%20Store&PAYMENTREQUEST_0_SHIPTOSTREET=1%20Main%20Terrace&PAYMENTREQUEST_0_SHIPTOCITY=Wolverhampton&PAYMENTREQUEST_0_SHIPTOSTATE=West%20Midlands&PAYMENTREQUEST_0_SHIPTOZIP=W12%204LQ&PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE=GB&PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME=United%20Kingdom&PAYMENTREQUEST_0_ADDRESSSTATUS=Confirmed&L_PAYMENTREQUEST_0_NAME0=ItemOne&L_PAYMENTREQUEST_0_QTY0=4&L_PAYMENTREQUEST_0_TAXAMT0=0%2e00&L_PAYMENTREQUEST_0_AMT0=3%2e89&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE0=%20%20%200%2e00000&PAYMENTREQUESTINFO_0_ERRORCODE=0
If anyone could give me an easy way to map this data to a C# object that would be great.
Is there any specific reason why you want it in JSON format? If its not requirement and if you can live with key value pair then here is one way you can process response as key value pair.
public partial class Form1 : Form
{
Dictionary<string, string> processedResponse = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string rawResponse = "TOKEN=EC%2XXXXXXXXXXXXXXXXXR&BILLINGAGREEMENTACCEPTEDSTATUS=0&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2015%2d01%2d02T21%3a11%3a30Z&CORRELATIONID=ab184fdba7a30&ACK=Success&VERSION=88%2e0&BUILD=14443165&EMAIL=test%40aol%2ecom&PAYERID=3XXXXXXXXXX4N&PAYERSTATUS=verified&BUSINESS=Test%20Biz%27s%20Test%20Store&FIRSTNAME=Joe&LASTNAME=King&COUNTRYCODE=GB&SHIPTONAME=Joe%20King%27s%20Test%20Store&SHIPTOSTREET=1%20Main%20Terrace&SHIPTOCITY=Wolverhampton&SHIPTOSTATE=West%20Midlands&SHIPTOZIP=W12%204LQ&SHIPTOCOUNTRYCODE=GB&SHIPTOCOUNTRYNAME=United%20Kingdom&ADDRESSSTATUS=Confirmed&CURRENCYCODE=GBP&AMT=15%2e56&ITEMAMT=15%2e56&SHIPPINGAMT=0%2e00&HANDLINGAMT=0%2e00&TAXAMT=0%2e00&INSURANCEAMT=0%2e00&SHIPDISCAMT=0%2e00&L_NAME0=ItemOne&L_QTY0=4&L_TAXAMT0=0%2e00&L_AMT0=3%2e89&L_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_ITEMHEIGHTVALUE0=%20%20%200%2e00000&PAYMENTREQUEST_0_CURRENCYCODE=GBP&PAYMENTREQUEST_0_AMT=15%2e56&PAYMENTREQUEST_0_ITEMAMT=15%2e56&PAYMENTREQUEST_0_SHIPPINGAMT=0%2e00&PAYMENTREQUEST_0_HANDLINGAMT=0%2e00&PAYMENTREQUEST_0_TAXAMT=0%2e00&PAYMENTREQUEST_0_INSURANCEAMT=0%2e00&PAYMENTREQUEST_0_SHIPDISCAMT=0%2e00&PAYMENTREQUEST_0_INSURANCEOPTIONOFFERED=false&PAYMENTREQUEST_0_SHIPTONAME=Joe%20King%27s%20Test%20Store&PAYMENTREQUEST_0_SHIPTOSTREET=1%20Main%20Terrace&PAYMENTREQUEST_0_SHIPTOCITY=Wolverhampton&PAYMENTREQUEST_0_SHIPTOSTATE=West%20Midlands&PAYMENTREQUEST_0_SHIPTOZIP=W12%204LQ&PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE=GB&PAYMENTREQUEST_0_SHIPTOCOUNTRYNAME=United%20Kingdom&PAYMENTREQUEST_0_ADDRESSSTATUS=Confirmed&L_PAYMENTREQUEST_0_NAME0=ItemOne&L_PAYMENTREQUEST_0_QTY0=4&L_PAYMENTREQUEST_0_TAXAMT0=0%2e00&L_PAYMENTREQUEST_0_AMT0=3%2e89&L_PAYMENTREQUEST_0_ITEMWEIGHTVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMLENGTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMWIDTHVALUE0=%20%20%200%2e00000&L_PAYMENTREQUEST_0_ITEMHEIGHTVALUE0=%20%20%200%2e00000&PAYMENTREQUESTINFO_0_ERRORCODE=0";
//Process response
processedResponse = ProcessResponse(rawResponse);
//Use received data e.g.
//Get First name
string fName = GetRecordValue("FIRSTNAME");
//Get Last name
string lName = GetRecordValue("LASTNAME");
}
private Dictionary<string,string> ProcessResponse(string response)
{
Dictionary<string, string> responseData = new Dictionary<string, string>();
if(!string.IsNullOrWhiteSpace(response))
{
string[] firstPass = response.Split(new char[] { '&' });
foreach(string pair in firstPass)
{
string[] secondPass = pair.Split(new char[] { '=' });
if(secondPass!=null && secondPass.Length>0)
{
responseData.Add(secondPass[0].Trim(), secondPass[1].Trim());
}
}
}
return responseData;
}
private string GetRecordValue(string record)
{
string recordValue = null;
if(processedResponse!=null)
{
if(!string.IsNullOrWhiteSpace(record) && processedResponse.ContainsKey(record))
{
recordValue= processedResponse[record];
}
}
return recordValue;
}
}
Still unsure what's the problem with dealing with it as a NameValueCollection.
E.g.
//NameValueCollection
//or use HttpUtility.ParseQueryString(some_string_of_names_values)
var foo = Request.QueryString;
var bar = foo["FIRSTNAME"]; //based on above this is "Joe"
Update:
It is response string which is being processed here and not request hence you wont be able to retrieve details using Request.QueryString
As stated in comments:
string rawResponse = "TOKEN=EC%2XXXXXXXXXXXXXXXXXR&BILLINGAGREEMENTACCEPTEDSTATUS=0&CHECKOUTSTATUS=PaymentActionNotInitiated&TIMESTAMP=2015%2d01%2d02T21%3a11%3a30Z&CORRELATIONID=ab184fdba7a30&ACK=Success&VERSION=88...."
var foo = HttpUtility.ParseQueryString(rawResponse); //NameValueCollection
var bar = foo["FIRSTNAME"]; //Joe
I've got a few web pages that have static data in HTML mark-up tables. By this, I mean, manually maintained text:
<table border="1" >
<tr><th>Number</th><th>Date</th><th>BW</th><th>WW</th><th>%</th><th>Type</th><th>CED</th><th>BW</th><th>WW</th><th>YW</th><th>Mlk</th><th>Me</th></tr>
<tr><td>313</td><td>9/16/2013</td><td>74</td><td>512</td><td>100</td><td>861U</td><td>3</td><td>-1.1</td><td>54</td><td>85</td><td>16</td><td></td></tr>
<tr><td>315</td><td>10/6/2013</td><td>-</td><td>-</td><td>-</td><td>W179</td><td>-</td><td>-</td><td>-</td><td>-</td><td>-</td><td>-</td></tr>
<tr><td>316</td><td>10/102013</td><td>72</td><td>595</td><td>94.2</td><td>W179</td><td>7</td><td>-2.3</td><td>53</td><td>80</td><td>21</td><td>-3</td></tr>
<tr><td>350</td><td>10/11/2013</td><td>71</td><td>703</td><td>100</td><td>W179</td><td>7</td><td>-2.3</td><td>46</td><td>72</td><td>20</td><td>-5</td></tr>
<tr><td>392</td><td>3/8/2013</td><td>61</td><td>651</td><td>100</td><td>RANGER</td><td>7</td><td>-2.3</td><td>52</td><td>82</td><td>20</td><td>-2</td></tr>
<tr><td>303</td><td>7/3/2013</td><td>63</td><td>-</td><td>97.1</td><td>W179</td><td>8</td><td>-3.2</td><td>N/A</td><td>82</td><td>21</td><td>-8</td></tr>
<tr><td>304</td><td>7/8/2013</td><td>62</td><td>-</td><td>97.1</td><td>W179</td><td>7</td><td>-3.9</td><td>N/A</td><td>69</td><td>20</td><td>-4</td></tr>
<tr><td>397</td><td>3/18/2013</td><td>78</td><td>621</td><td>100</td><td>STATEMENT</td><td>6</td><td>-2.7</td><td>55</td><td>84</td><td>19</td><td>5</td></tr>
<tr><td>395</td><td>3/17/2013</td><td>63</td><td>716</td><td>94.2</td><td>STATEMENT</td><td>5</td><td>-2.7</td><td>54</td><td>85</td><td>19</td><td>5</td></tr>
<tr><td>390</td><td>3/6/2013</td><td>66</td><td>583</td><td>94.2</td><td>ENVY</td><td>2</td><td>-0.6</td><td>55</td><td>80</td><td>23</td><td>2</td></tr>
<tr><td>388</td><td>3/4/2013</td><td>53</td><td>621</td><td>100</td><td>STATEMENT</td><td>10</td><td>-5.1</td><td>49</td><td>82</td><td>20</td><td>2</td></tr>
<tr><td>300</td><td>3/22/2013</td><td>61</td><td>633</td><td>100</td><td>RANGER</td><td>8</td><td>-2.8</td><td>49</td><td>81</td><td>19</td><td>-2</td></tr>
<tr><td>379</td><td>2/1/2013</td><td>55</td><td>518</td><td>100</td><td>STATEMENT</td><td>8</td><td>-4.1</td><td>61</td><td>98</td><td>18</td><td>1</td></tr>
<tr><td>398</td><td>3/20/2013</td><td>62</td><td>664</td><td>100</td><td>RANGER</td><td>6</td><td>-2.3</td><td>53</td><td>83</td><td>20</td><td>0</td></tr>
<tr><td>384</td><td>2/10/2013</td><td>61</td><td>650</td><td>100</td><td>ENVY</td><td>3</td><td>-1</td><td>50</td><td>70</td><td>19</td><td>4</td></tr>
<tr><td>369</td><td>1/30/2013</td><td>76</td><td>651</td><td>100</td><td>STATEMENT</td><td>5</td><td>-2.4</td><td>60</td><td>99</td><td>20</td><td>8</td></tr>
<tr><td>373</td><td>1/21/2013</td><td>71</td><td>433</td><td>100</td><td>STATEMENT</td><td>4</td><td>-1.6</td><td>55</td><td>89</td><td>17</td><td>3</td></tr>
<tr><td>393</td><td>3/10/2013</td><td>63</td><td>717</td><td>100</td><td>STATEMENT</td><td>3</td><td>-4.6</td><td>51</td><td>91</td><td>20</td><td>5</td></tr>
<tr><td>389</td><td>3/8/2013</td><td>72</td><td>723</td><td>88.3</td><td>ENVY</td><td>4</td><td>-0.6</td><td>54</td><td>76</td><td>24</td><td>2</td></tr>
<tr><td>364</td><td>10/1/2012</td><td>60</td><td>574</td><td>100</td><td>RANGER</td><td>1</td><td>0.4</td><td>56</td><td>84</td><td>21</td><td>2</td></tr>
</table>
Currently, I am contemplating using a WebClient.DownloadString to pull all of the text in, and try to create an XML file out of it by parsing each row <tr>.
That sounds tedious, and I would rather not reinvent the wheel. Besides, a few good solutions would give me something to look at for ideas on how to best approach writing my version.
Has anyone come across some code that can do this?
I've started, to give you an idea of what I'm working on:
private const string XML_DATA = "App_Data/page_data.xml";
private const string TABLE_START = "<table>";
private const string TABLE_STOP = "</table>";
private string[] TABLE_ROW = { "<tr>", "</tr>" };
private string[] TABLE_HEAD = { "<th>", "</th>" };
private string[] TABLE_DET = { "<td>", "</td>" };
private void load_data() {
if (!File.Exists(XML_DATA)) {
string HtmlText;
using (var client = new WebClient()) {
HtmlText = client.DownloadString(Server.MapPath("/Sales.aspx"));
}
if (!String.IsNullOrEmpty(HtmlText)) {
var lcTxt = HtmlText.ToLower();
int len0 = TABLE_START.Length;
int tStart = lcTxt.IndexOf(TABLE_START) + len0;
int tStop = lcTxt.IndexOf(TABLE_STOP);
if ((len0 < tStart) && (tStart < tStop)) {
var tableString = HtmlText.Substring(tStart, tStop - tStart);
var tableRows = tableString.Split(TABLE_ROW, StringSplitOptions.RemoveEmptyEntries);
foreach (var row in tableRows) {
if (-1 < row.IndexOf(TABLE_HEAD[0])) {
//
} else {
//
}
}
}
}
}
}
Of course, you can see that is already going to fail, because the Markup using <table border="1">.
Yes, easy to fix, but I'd rather have a working guide that has already been through a lot of debugging steps.
UPDATE: I tried using XmlDocument's LoadXml method, but it can't seem to read basic HTML:
You definitely shouldn't be trying to parse that manually. Other people have already solved that problem.
If your markup is valid XML (and from what you've shown us, it looks like it is), then you can just parse it as XML:
XmlDocument doc = new XmlDocument();
doc.LoadXml(HtmlString);
doc.Save("myfile.xml");
But for that matter, if it's already valid XML markup, and all you need to do is save it as a file, then you don't need to parse it. Just save it:
File.WriteAllText("myfile.xml", HtmlString);