A little side C# project had me needing to read an XML file
coming from an external source. It has been a while since I did battle with XML
as my personal preference is for JSON wherever possible as I feel the latter is
more about the data and less about the structure.
Anyway, this was an opportunity to try a Linq query against an XML file.
Anyway, this was an opportunity to try a Linq query against an XML file.
var xdoc = XDocument.Load(“path to XML file”);
List < Feed > newFeeds = (from lvl in xdoc.Descendants("outline")
select new Feed
{
FeedTitle =
lvl.Attribute("title").Value,
RSSUrl =
lvl.Attribute("xmlUrl").Value,
MainUrl =
lvl.Attribute("htmlUrl").Value
}).ToList();
This statement reads an XML file and creates a list of
classes (Feed) based upon the file content.
An elegant and clear method that shifts the processing from
being about the file structure to concentrating on the data. OK – this is an
abstraction – so things might well go wrong.
So course you can’t actually implement the code above no
matter how elegant – you have to let the real world of dirty and incomplete files in. Something like:
var xdoc = XDocument.Load(“Path to XML file”);
List < Feed > newFeeds = (from lvl in xdoc.Descendants("outline")
where (string)lvl.Attribute("type") != null
select new Feed
{
FeedTitle = (string)lvl.Attribute("title") != null ? lvl.Attribute("title").Value
: "",
RSSUrl = (string)lvl.Attribute("xmlUrl") != null ? lvl.Attribute("xmlUrl").Value : "",
MainUrl = (string)lvl.Attribute("htmlUrl") != null ? lvl.Attribute("htmlUrl").Value : ""
}).ToList();
Where the objects (say lvl.Attribute("type")) is cast to a string and then that string is tested for null.
The same project had me
playing around with some large strings where the .NET StringBuilder class is usually your friend. I needed to locate one or more occurrence of a given string and
insert some additional characters near that location. The StringBuilder class
has an Insert() method that can inject all sorts of types into a specified location
BUT no inbuilt way to find that location.
Time for one of those new-fangled Extension methods which are very straightforward to implement.
Time for one of those new-fangled Extension methods which are very straightforward to implement.
I started with this:
internal static class Extensions
{
public static int IndexOf(this StringBuilder sb, string value, int startIndex, bool ignoreCase)
{
int index;
int length = value.Length;
int maxSearchLength = (sb.Length - length) + 1;
for (int i = startIndex; i < maxSearchLength; ++i)
{
if (sb[i] == value[0] || (Char.ToLower(sb[i]) == Char.ToLower(value[0]) && ignoreCase))
{
index = 1;
while ((index < length) && (sb[i + index] == value[index] || (Char.ToLower(sb[i + index]) == Char.ToLower(value[index]) && ignoreCase)))
++index;
if (index == length)
return i;
}
}
return -1;
}
}
But I am lazy so then added
the obvious alternate method signatures to the class:
public static int IndexOf(this StringBuilder sb, string value, int startIndex)
{
return IndexOf(sb, value, startIndex, false);
}
public static int IndexOf(this StringBuilder sb, string value)
{
return IndexOf(sb, value, 0, false);
}
public static int IndexOf(this StringBuilder sb, string value, bool ignoreCase)
{
return IndexOf(sb, value, 0, ignoreCase);
}
And it just worked:
sPos = myStringBuilder.IndexOf("<iframe", true);
This project also allowed me
to try out an asynchronous method without the hassle of messing with Threads even
wrapped as a BackgroundWorker.
await Task.Run(()
=> doFeedCheck()); // run doFeedCheck()
on another thread
No comments:
Post a Comment