What does curly brackets do in Xpath? - c#

I am reading a legacy framework written in C#, there is a constant string defined as following:
private const string NAVBAR_PANEL_TEMPLATE =
".//*[#id='navbar']//*[contains(#class, 'platform-nav-{0}')]";
This string is to be used for element-searching by xpath. To my understanding, it can be translated as: "looking for elements whose ids are equal to 'navbar', under those matching elements, looking for elements whose class contains 'platform-nav-{0}'".
I am really confused by the last {0}, what does it represent?

It is likely not part of the XPath expression. The code is likely passing NAVBAR_PANEL_TEMPLATE to String.Format() and substituting a value in place of {0}.

Related

How to check if string is valid xml name

I want quick function which may be part of my xml parser, I do not want to parse whole string and check if it correct xml.
This is not really doable without parsing, or at least—in a limited form—without using a regular expression. Names in XML permit different characters as the first character and as second and further characters — see the Name production.
Should you implement IsValidXmlChar without a context, i.e. just checking if the given character is a NameChar, as per the XML specification, the output of your example would be GridAttributeStuff.
So you should at least tokenize the input text to retrieve valid names, and parse the input to retrieve element names, i.e. output Grid in your example.
To check if a string is a XML name, the XmlReader class offers the IsName static method. To categorize characters in an XML text, there is the XmlCharType struct in .NET Framework as well as in .NET Core, but it's internal.

C# Dynamic Linq: Strings are assumed to be integers?

I'm using the System.Linq.Dynamic library found here, which is simply an upload of Microsoft's library to be accessible via NuGet: https://github.com/kahanu/System.Linq.Dynamic
In my code, I have this function that gets a list of objects from a database that match a certain property. It needed to be as flexible as possible, so the parameters consist of three strings;
One for the "order by" statement
One for the property to match's name
One for the expected property's value
Here's the line of code that's giving me trouble:
public IQueryable<T> GetByProperty(string propertyName, string propertyValue,
string orderStatement)
{
return _context.Set<T>()
.OrderBy(orderStatement)
.Where(propertyName + " = " + propertyValue);
}
Here are the possible scenarios;
propertyValue contains only numbers: the query works perfectly.
propertyValue starts with numbers but has letters in it: the following error appears: Operator '=' incompatible with operand types 'String' and 'Int32'
propertyValue is anything else: the following error appears: No property or field '[the first part of the "propertyValue string, up until it meets an empty space, a "-" or some other specific characters]' exists in type '[Class name of <T>]'
I've tried using single quotes to surround my string, but I then get the error: 'Character literal must contain exactly one character'
I've also desperately tried to add ".ToString()" at the end to try and trick something into working, but I found the error: Digit expected.
Is there another way to use the "Where" clause, in Linq and Dynamic Linq, that would support the flexibility I'm trying to have using this structure?
You need to know the type of the property and format the value accordingly. If it is a string, enclose it in double quotes. i.e. name = "John" but age = 20.
It does not depend whether the value looks like a number or not.
If the type of the property is a number type then the value must be a number as well and not be enclosed in quotes.
If the type of the property is a string then the value must be enclosed in double quotes, even if the value is a number (e.g. code = "3").

What data structure should I use to store a collection of items in C#?

I have following string : [Value:"Car" - Name:"Manufactor" [Value:"Audi" - Name:"A6"][Value:"BMW" - Name:"M4"]]]
I need to split the string and save data into suitable data structure. Starting bracket "[" indicates the beginning of the collection, and
matching ending bracket "]" indicates the end of the collection. The "-" character seperates key and values. So I was wondering what is most
logical datastructure to use here? Is using a tree good solution? I have splitted the string up in parts, I only need help to choose a logical datastructure.
Thanks!
Using a tree is not a good solution, as you don't have something like branches with multiple leafs in your structure.
Without knowing your use case, I would use a list or an array of Car-Objects, each having a property Name and Manufacturer.
It looks like a sort of tree, or possibly nested dictionaries if there are other types than Car. Or a simple dictionary, like; Dictionary<Manufacturer, List<CarModels>>
string is not well-formed I guess (3 opening brackets and 4 closing ones)
that makes your string ambiguous, especially with these 3 closing brackets at the end
You can just do the same as what JavaScriptSerializer does. It returns a Dictionary(Of String, Object) and Object is either a string or an other Dictionary(Of String, Object).
The best way would be to have proper classes and good property name and store the information.

Matching and replacing function expressions

I need to do some very light parsing of C# (actually transpiled Razor code) to replace a list of function calls with textual replacements.
If given a set containing {"Foo.myFunc" : "\"def\"" } it should replace this code:
var res = "abc" + Foo.myFunc(foo, Bar.otherFunc( Baz.funk()));
with this:
var res = "abc" + "def"
I don't care about the nested expressions.
This seems fairly trivial and I think I should be able to avoid building an entire C# parser using something like this for every member of the mapping set:
find expression start (e.g. Foo.myFunc)
Push()/Pop() parentheses on a Stack until Count == 0.
Mark this as expression stop
replace everything from expression start until expression stop
But maybe I don't need to ... Is there a (possibly built-in) .NET library that can do this for me? Counting is not possible in the family of languages that RE is in, but maybe the extended regex syntax in C# can handle this somehow using back references?
edit:
As the comments to this answer demonstrates simply counting brackets will not be sufficient generally, as something like trollMe("(") will throw off those algorithms. Only true parsing would then suffice, I guess (?).
The trick for a normal string will be:
(?>"(\\"|[^"])*")
A verbatim string:
(?>#"(""|[^"])*")
Maybe this can help, but I'm not sure that this will work in all cases:
<func>(?=\()((?>/\*.*?\*/)|(?>#"(""|[^"])*")|(?>"(\\"|[^"])*")|\r?\n|[^()"]|(?<open>\()|(?<-open>\)))+?(?(open)(?!))
Replace <func> with your function name.
Useless to say that trollMe("\"(", "((", #"abc""de((f") works as expected.
DEMO

C# string masking/formatting/filtering with or without regex

Hopefully this isn't too complicated, I just can't seem to find the answer I need.
I have a string with variables in, such as: this is a %variable% string
The format of the variables within the string is arbitrary, although in this example we're using the filter %{0}%
I am wanting to match variable names to properties and ideally I don't want to loop through GetProperties, formatting and testing each name. What I'd like to do is obtain "variable" as a string and test that.
I already use RegEx to get a list of the variables in a string, using the given filter:
string regExSyntax = string.Format(syntax, #"(?<word>\w+)");
but this returns them WITH the '%' (e.g. '%variable%') and as I said, that filter is arbitrary so I can't just do a string.Replace.
This feels like it should be straight-forward....
Thanks!
"(?<word>\w+)"
Is just capturing anything alphnumeric and putting it into a named capturing group called "Word"
You might be interested in learning about lookbehind and lookahead. For example:
"(?<=%)(?<word>\w+)(?=%)"
You can make it a bit more generic with putting your filter in a seperate variable:
string Boundie = "%";
string Expression = #"(?<=" + Boundie + #")(?<word>\w+)(?=" + Boundie + #")";
I hope this is anywhere near what you are looking for.
Given that your regex syntax is: string regExSyntax = string.Format(syntax, #"(?<word>\w+)");, I assume you're then going to create a Regex and use it to match against some string:
Regex reExtractVars = new Regex(regExSyntax);
Match m = reExtractVars.Match(inputString);
while (m.Success)
{
// get the matched variable
string wholeVar = m.Value; // returns "%variable%"
// get just the "word"
string wordOnly = m.Groups["word"].Value; // returns "variable"
m = m.NextMatch();
}
Or have I completely misunderstood the problem?
Acron,
If you're going to roll-your own script parser... apart from being "a bit mad", unless that's the point of the exercise (is it?), then I strongly suggest that you KISS it... Keep It Simple Stoopid.
So what denotes a VARIABLE in your scripting syntax? Is it the percent signs? And they're fixed, yes? So %name% is a variable, but #comment# is NOT a variable... correct? The phrase "that filter is arbitrary" has me worried. What's a "filter"?
If this isn't homework then just use an existing scripting engine, with existing, well defined, well known syntax. Something like Jint, for example.
Cheers. Keith.

Categories

Resources