Parsing Resx file with C# crashes on relative paths - c#

Out of the sheer frustration of having to copy resx data into word to get the word count
i've started to write my own tool to do so.
Well that made me run into an issue.
i have icons and such things in the Resources.resx file.
and they have relative paths according to the project they are being used int.
Which they should have obviously.
Well when i try to parse the Resx file in another application to count the words from the Value column.
i am getting errors as they can't parse the relative path. they end up going to folders that do not exist in my wordcount application.
Does any of you have an idea how i can fool the app into looking in the right folder when parsing these values?
i'm not quite sure why it is parsing those values to begin with.
it should just grab the string that's all i care about.
i'm using the ResXReader
ResXResourceReader reader = new ResXResourceReader(filename);
foreach(System.Collections.DictionaryEntry de in reader)
{
if (((string)de.Key).EndsWith(".Text"))
{
System.Diagnostics.Debug.WriteLine(string.Format("{0}: {1}", de.Key, de.Value));
}
}
I found this here: Word Count of .resx files
It errors out on the foreach.
..\common\app.ico for example.
anyone have an idea on how to do this?

Alright.
So the solution was a little easier than expected.
i was using an outdated Class.
I should have been using XDocument instead of XmlDataDocument
secondly LINQ is the bomb.
all i had to do was this:
try
{
XDocument xDoc = XDocument.Load(resxFile);
var result = from item in xDoc.Descendants("data")
select new
{
Name = item.Attribute("name").Value,
Value = item.Element("value").Value
};
resxGrid.DataSource = result.ToArray();
}
and you can even allow empty strings if you cast those attributes/elements to (String)
Hope this helps someone!

Try to use ResXResourceReader for this purpose - see http://msdn.microsoft.com/en-us/library/czdde9sc.aspx

Related

Taglib not saving full tags

I'm using taglib# to input mp3 title and artist names as metadata parsed from file names. To do this, I'm essentially looping through a list of file names, parsing the names, creating a taglib file, changing the tags, then saving and disposing of the taglib file. Oddly enough, in my circumstances, I noticed that there seems to be a maximum length for strings that tags can take as input after the first file has been successfully changed.
Here is a small scale example I am running now.
foreach (string path in files)
{
using (TagLib.File f = TagLib.File.Create(path))
{
f.Tag.Title = "000000000011111111112222222222333333333344444444445555555555"
f.Save();
}
}
As output, the first file touched has the correct title field:
000000000011111111112222222222333333333344444444445555555555
But each file after it only has a portion:
000000000011111111112222222222
You can see it in explorer:
The results are the same no matter the field modified. Also, explicitly calling Dispose() on the taglib file does not change anything. Why could this be?
It seems I always ask a question right when I'm on the brink of finding an answer. I did a little more digging and found that this answer also solves my problem. In short, make sure that the right version of Id3 is in use.
Aside: I found that this also solved another issue I was having with unicode being turned into question marks in the output. A nice bonus!

How to create a text File in solution Explorer?

It's a bit hard to explain but I'll try my best.
I'm not asking how to create a text file or read text file and display. It's more basic than that.
My question is: I've written a paragraph of text file but I don't know how to put it under Solution Explorer, so my program can reference it instead of writing it many times.
Here is one of my coding with a sample string and I have a couple of them using the same text but different tasks. Here I manually(?) wrote the text(string) that I want to save as text file so I can refer to.
string st = "I like apples. I like red apples. I like red apples than green apples";
string result = st.OrderByDescending(s => s.Split(' ').Count()).First();
this.lblMostWordsInSen.Text = result;
Actually, the code above has an error under Split, it says char doesn't contain a definition for Split. How do I fix it?
I've found this coding below "text_file_name.txt" or (#"d:\test.txt") is what I want but file should not be stored in my D drive. It should be stored in my program (Solution Explorer?) I did it in Web application but I don't know how to do in WinForm.
string filename = "Alice-in-Wonderland.txt";
StreamReader sr = new StreamReader("TestFile.txt")
String[] values = File.ReadAllText(#"d:\test.csv").Split(',');
And finally how to call my file is my last question...
Thanks in advance~
Actually, the code above has an error under Split, it says char
doesn't contain a definition for Split. How do I fix it?
string result = st.OrderByDescending(s => s.Split(' ').Count()).First();
it is because string st is a group of characters. in fact it is
st[0],st[1],...,st[st.Length-1]
when you call st.OrderByDescending and supply a lambda expression like s => ..., s does not represent the whole string(st), it just represents elements of st which their type is char and this results to the error we have mentioned above.
You can add a text file to your projects. and if you want to read them you can just read them like this
File.ReadAllText("yourfilename")
but remember to select your file in solution explorer and right click and click properties, then change "Copy to output directory" property to the "Copy always" or "Copy if newer" based on your situation, this will cause that when you build your project, this file will be copied in the directory where your executable file is and you do not need path of it to access it.
you can also go to Build Events tab of your project properties and set actions that will execute when you try to build your project, for example you can set an action to copy "yourfile" to a folder named "text resources" in your build directory, in this approach you can handle more complex situation for example when you have lot of this kind of resources in your project.
you can read this for more information on Build Events
Instead of using the Resources of your program as suggested in the comments already, you could also use a Settings file if you want these Settings to be easily manipulated.
Check this article out: http://msdn.microsoft.com/en-us/library/aa730869(v=vs.80).aspx

In C#, is there a way to access xml comments (the tags in VS) in the source code at runtime?

In Visual Studio, xml comments can be added to methods/classes to provide documentation.
See http://msdn.microsoft.com/en-us/magazine/cc302121.aspx.
Visual Studio generates files from these xml comments and exports them, so they are accessible for sure.
My question is, is there a class of some sort that let's the program access the xml text at runtime? (I think the brute force way is to parse the exported files, but that's not a neat solution)
The reason I want to do this is because I'm making a kind of a helper program for a larger program, so I want to output the xml comments to screen. I have the property name through reflection, so is there a way to feed the name back in to some class and get the xml documentation?
I tried searching already, but I couldn't find anything. I might be wording it badly. Is this possible?
XML comments get stripped out of the executable - that's why there is a special compiler flag to generate the XML documentation from them, so they don't get lost.
There are tools that help you generate HTML help and other formats from these XML files.
As far as I now, the XML comments are not saved as metadata in the assembly binary file (.exe or .dll). So the only option is to directly parse the XML file generated by Visual Studio.
Try DocsByReflection.
// From type.
var typeDoc = DocsService.GetXmlFromType(typeof(Stub));
// From property.
var propertyInfo = typeof(Stub).GetProperty("PropertyWithDoc");
var propertyDoc = DocsService.GetXmlFromMember(propertyInfo);
// From method.
var methodInfo = typeof(Stub).GetMethod("MethodWithGenericParameter");
var methodDoc = DocsService.GetXmlFromMember(methodInfo);
// From assembly.
var assemblyDoc = DocsService.GetXmlFromAssembly(typeof(Stub).Assembly);

XML DocumentWriter - Stop empty elements appearing over two lines in .NET

I am using the XML document object in VB.NET to manipulate XML.
My application creates a new XML fragment and updates the XML via the innerXML method:
reasonFrag.InnerXml = String.Format("<ReasonForPayment>{0}</ReasonForPayment>", reason)
This produces the correct XML output on most occasions, e.g.
<ReasonForPayment>reason</ReasonForPayment>
If the reason string is empty I get element spanning two lines in the XML as follows:
<ReasonForPayment>
</ReasonForPayment>
I am looking for a way of keeping the element on a single line while maintaining the same format, e.g.
<ReasonForPayment></ReasonForPayment>
The alternative <ReasonForPayment /> is not acceptable (third party application wont accept it).
Thanks
Steven
I think the best way to handle this would be to do something like this:
if (reason == null | reason.Trim() == "")
{
reasonFrag.IsEmpty = true;
}
else
{
reasonFrag.InnerText = reason.Trim();
}
This changes the output to
<ReasonForPayment/>
if(string.IsNullOrEmpty(reason))
{
reasonFrag.InnerXml = "<ReasonForPayment></ReasonForPayment>"
}
else
{
reasonFrag.InnerXml = String.Format("<ReasonForPayment>{0}</ReasonForPayment>", reason)
}
Not tested but maybe something like
edit threw it into LinqPad, works just fine for what you need.
public static string ToXmlFragment(this object input, string element)
{
//extension method, place in a static class somewhere
return string.IsNullOrEmpty(input.ToString()) ?
string.Format("<{0}></{0}>",element) :
string.Format("<{0}>{1}</{0}>",element,input);
}
reasonFrag.InnerXml = reason.ToXmlFragment("ReasonForPayment");
The solution to my problem was unusual. When reading or writing files in .NET using streamreader/writer, textreader/writer and the XMLDocument object, the document format changes depending on the file extension. So for example reading a file with a XML extension, the file is treated and formatted as XML. This was causing my original problem, a empty element was output over two lines with a CRLF inserted. The solution was to output the steam to a file with a .txt extension and then rename the file to XML, then my formatting was preserved.

fine and fast csv reader

I m using Lumenworks CSV reader and i must say i m not very happy with it with how it works so far.
I m parsing thousands of csv files within an hour and there is always a problem, either throws an exception complaining about bad records or skewing the columns etc.
Can you recommend a fine CSV reader, it doesnt have to be a free one, but bug free.
Thank you.
FileHelpers Open Source Library http://www.filehelpers.net/
Try CsvHelper (a library I maintain). It's also available on NuGet.
You cite that you are receiving exceptions and such from the files. While these may be undesired, have you investigated the cause?
You might just want to use one of the current parsers that are on the table and when an exception occurs, try an alternative or/and handle the scenarios with custom code. I know it's not exactly what you are looking for but the problem may not be the tools you are using but the input the tools are receiving...
You could also move the offending file to a separate directory (in code) to look at a bit later and get what will process, processed.
There is a CSV parser built into .NET.
From http://coding.abel.nu/2012/06/built-in-net-csv-parser/:
// TextFieldParser is in the Microsoft.VisualBasic.FileIO namespace.
using (TextFieldParser parser = new TextFieldParser(path))
{
parser.CommentTokens = new string[] { "#" };
parser.SetDelimiters(new string[] { ";" });
parser.HasFieldsEnclosedInQuotes = true;
// Skip over header line.
parser.ReadLine();
while (!parser.EndOfData)
{
string[] fields = parser.ReadFields();
yield return new Brand()
{
Name = fields[0],
FactoryLocation = fields[1],
EstablishedYear = int.Parse(fields[2]),
Profit = double.Parse(fields[3], swedishCulture)
};
}
}
You have to check the input files.I think these tool don't stop at format check because they aim for quantity stuff (skiping erroneous data to treat the maximum of files).
In the real world you rarely see a stream of clean CSV. Drivers tend to give their own kind:
-no quotes
-semi colon instead of comma
Files that are generating errors usually come from the same source.
It's been a long time since I used it, but FileHelpers does CSV parsing with lots of options.

Categories

Resources