3

Im trying to search a file and see if any line contains the word Description1 AND if somewhere on that particular line two quotation marks appears directly after each other.

I have found various ways to delete or replace them but I want to keep them.

foreach (var line in File.ReadLines(FileName))
   {
    if (line.Contains ("Description1") )
       {
        MessageBox.Show ("Description1 found");

           if (line.Contains (@"""") )
              {                                                 
               MessageBox.Show ("ERROR! Empty Description1 found.");
              }
        }
}

The file searched looks similar to this

 propertyDescriptor="22004" PropertyName="Description1" PropertyType="Part" PropertyValue="Cat"   
 propertyDescriptor="22004" PropertyName="Description1" PropertyType="Part" PropertyValue=""   
 propertyDescriptor="22006" PropertyName="Description2" PropertyType="Part" PropertyValue=""   

The errorcheck schould only detect the error on the second row where both Description1 and the two quoation marks exist.

My problem is that I get an error on every instance of the text Description1.

Any good ideas?

Thanks in advance.

Hans Kesting
  • 38,117
  • 9
  • 79
  • 111
  • So you want parsing code that can deal with Empty Strings for `PropertyValue`? Seems simple enough, given that `""` is a valid string in .NET. You just want to make sure to run the inputs through `IsNullOrWhitespace()` before you process them. Maybe you even want to replac those empty strings with a NULL, to make later processing easier. – Christopher Feb 10 '20 at 11:10
  • Your Code above doesn't respect the order of the tokens you are interested in. I suggest to use something like string.Split() (probably even nested) and write a better parser. – David J Feb 10 '20 at 11:16
  • `Contains` is too big a hammer for what you want to do. Take a look at `IndexOf` instead - it has overloads that let you start search from a particular offset (like previous search result) within the string. – 500 - Internal Server Error Feb 10 '20 at 11:19
  • @Christopher The file is generated by another software. Im only given the file to process it. So I cant see how to use your suggestion, but then again I have not used it at all before but it doesnt seem to be useful here... Right? – Tomas Nordström Feb 10 '20 at 11:20
  • You could write a regex. – AliK Feb 10 '20 at 11:21
  • 1
    I would check for line.Contains("PropertyName=\"Description1\"") and line.Contains("PropertyValue=\"\"") – Sir Rufo Feb 10 '20 at 11:22
  • @DavidJulitz I have tried different ways but I have not succeded with string.Split() only because that the line can include more or less data than in my example. There might be propertyclassification, propertyowner etc. Do you maybe have any good suggestions? – Tomas Nordström Feb 10 '20 at 11:23
  • 1
    BTW line.Contains(@"""") is the same as line.Contains("\"") – Sir Rufo Feb 10 '20 at 11:24
  • @TomasNordström You have a file. You need to parse it. The parsing should not bug out at `""` for any key/value pair. – Christopher Feb 10 '20 at 11:24
  • @TomasNordström If the file is more complex than in your example data, then you can probably use the XML parser as suggested by Enigmativity. But this can become overkill depending on the size of the file you want to parse. Another way would be to follow the string.Split() approach and iterating over all Tokens and split, parse and analyse them more. – David J Feb 10 '20 at 12:28
  • FYI don't add "SOLVED" to the title, but instead accept an answer. See [*What should I do when someone answers my question?*](https://stackoverflow.com/help/someone-answers) – Hans Kesting Feb 11 '20 at 11:52

2 Answers2

6

Use line.Contains("\"\"") instead of line.Contains(@"""") as line.Contains(@"""") will search for " not "".

Substituted in your code:

foreach (var line in File.ReadLines(FileName))
{
    if (line.Contains ("Description1") )
    {
        MessageBox.Show ("Description1 found");

        if (line.Contains ("\"\"") )
        {                                                 
            MessageBox.Show ("ERROR! Empty Description1 found.");
        }
    }
}
Tomas Chabada
  • 2,869
  • 1
  • 17
  • 18
  • 1
    @DavidJulitz It does compile if you substitute as stated. Incidentally `line.Contains(@"""""")` can also be used. – Ian Feb 10 '20 at 11:33
  • It surely does, check it please @David Julitz – Tomas Chabada Feb 10 '20 at 11:35
  • Either use `@""""""` or use `"\"\""` - in a verbatim string literal (with @) you need to escape a " by doubling it and the `\ ` is just a backslash, in a regular string literal you need to escape a quote with a backslash – Hans Kesting Feb 10 '20 at 11:42
  • @DavidJulitz yes, you're right, probably should look have `line.Contains("PropertyValue=\"\"")` – Ian Feb 10 '20 at 11:50
  • @TomasNordström Please consider marking this answer as the correct one – Tomas Chabada Feb 10 '20 at 12:58
0

Since the input text looks a lot like valid XML attributes, I'd suggest trying to see if parsing it as XML might actually help.

Try this:

var errors =
    File
        .ReadLines(FileName)
        .Select(x => $"<root {x} />")
        .Select(x => XDocument.Parse(x))
        .Where(x => x.Root.Attribute("PropertyName").Value == "Description1")
        .Where(x => x.Root.Attribute("PropertyValue").Value == "")
        .ToArray();

In your sample data this produces the following for me:

<root propertyDescriptor="22004" PropertyName="Description1" PropertyType="Part" PropertyValue="" />

You certainly could play around with this fairly clean query to get it to output the messages that you wish.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172