Reference to root element as key in JSON Path Expression - jsonpath

I have a JSON like this
{
"a" : 1,
"key_to_find" : "value_of_key",
"nested" : {
"value_of_key" : "real_value",
"b" : 2
}
}
I want to create a JSON Path expression to get "real_value", but I don't now the key "value_of_key" so I need to dynamically reference it.
I tried something like:
$.nested['$.key_to_find']
but it doesn't work.
How can I reference to root element value as key to get children values? Is that possible?
I need to use it inside AWS Step Functions, so no programming languages/libraries can be used.

References like this aren't part of JSON Path, though I think since you're using them inside AWS, you'll need to see exactly what they support. It varies. Widely.
We (the team working on the coming specification) have looked at the idea of a key() or index() function, however. You may find this discussion enlightening as well.

Related

Determine whether a list of paths contains a dynamic path

I have a function in my firebase rules file userRolesIncludesPermission, this function checks a property on the user to determine whether that user has a certain permission on their role, it does so by comparing references.
This works as expected in the firebase rules file when used for security rules for firestore. Unfortunately this does not work as expected with "storage".
After research I found out that the problem is the comparison between the references from the permissions list under user.data.roles[0] and my custom made path.
Is there any better way to produce a path that can be recognizable using a list function?
Is it an unknown limitation of storage security rules?
Note that the function getRootCollectionDocRef works perfectly when I try to build a queryable path even in the same request (for example when I try earlier in the code to query the user)
Another note is that in the rules playground (console debugger) it works. But in an actual request from the website (dev, for now) it doesn't.
function getRootCollectionDocRef(collection, docId) {
return /databases/(default)/documents/$(collection)/$(docId);
}
function userRolesIncludesPermission(user, permissionId) {
return firestore.get(user.data.roles[0]).data.permissions.hasAll([getRootCollectionDocRef("permissions", permissionId)]);
}
I tried to use every available list function such as "in", "hasAny" etc.
I tried to build the path while converting it with path() function.
I tried to convert to a set.
I tried to use a hard coded non-dynamic path. It failed as long as I use a custom-made path.
However when trying to query the path with a fixed index (i.e firebase.get(permissions[1]) it worked. But this is an invalid practice. I have to make it dynamic, but the problem is that I can't loop over the list and convert the paths to strings on the fly.
Thanks in advance!!

How to get away from Non-capitalized key value for Record construction?

I am using graphql, nexus-plugin-prisma, prisma to build a backend application using ReScript. The problem I face is that there are some columns starting with capital letter, and I want to set types for such schemas using records instead of objects. (to make use of pattern matching utility)
But ReScript prevents capitalized letters to appear as the very first character of a key of a record. Is there any way that I can somehow get away with this issue? Any help would be appreciated.
Usually when dealing with graphQL, the best way to circumvent this issue is to make use of graphQL aliasing feature:
fragment Foo on foo {
uncapitalizedAlias: CapitalizedName
}
edit: I don't know if the records you're trying to use are defined beforehand or generated by your GraphQL client, but you have other more general solutions when you want to bind to JS objects with capitalized names:
you can make use bs.as to change the name of the field (works both in Ocaml/Reason and Rescript syntaxes):
type myGQLrecord = {
#bs.as("CapitalizedName")
uncapitalizedName: string,
}
or you can directly use any identifier name you want for your field thanks to this feature of rescript syntax (works also for value identifiers):
type myGQLrecord = {
\"CapitalizedName": string
}
In my opinion, it makes it a bit more cumbersome to use though.

Understanding some code

I have an application which was built a few years ago. I came across a section of code that baffled me as the functionality this provides throughout the ASP .Net application is great but i just dont understand it. Perhaps its the [] throwing me off but i think it could be some C# code converted to VB .Net.... Not sure but wondered if anyone understands this and if so could they share what its doing
The code in an NotInheritable class
Public Overloads Function [Get](Of B)() As B
Dim myType = GetType(B)
Return DirectCast([Get](myType), B)
End Function
I understand it overloads a function but
Why are the [] there for and what do they mean? When would you use them? If i remove them i have a compiler error.
Get in VB .Net is used in properties so is this some shortcut access to a property somewhere? Or
where could i view which method its overloading?
I've used code similar to List(Of Customer), IQueryable(of Customer) but how has (Of B) allowed in this manner?
I have read up on MSDN and researched around. The only thing that comes to mind is either some C# syntax conversion or some old VB6 syntax which the original developer must have used whilst creating the application.
Appreciate any clarification on this.
Because Get is part of Visual Basic Language Keywords. You need the bracket to indicate you want to use them as a method/property name.
Here is an excerpt from Microsoft on Keywords as Element Names in Code (Visual Basic):
Any program element — such as a variable, class, or member — can have
the same name as a restricted keyword. For example, you can create a
variable named Loop. However, to refer to your version of it — which
has the same name as the restricted Loop keyword — you must either
precede it with a full qualification string or enclose it in square
brackets ([ ]), as the following example shows.
1) Brackets allow you to use reserved words as identifiers (like the ampersand in c#).
2) It appears to be a bad naming decision. If they wanted to hide an existing member they could have used the Shadows keyword.
3) You'll need to examine the inheritance hierarchy. Start with the most recent parent.
4) It is calling a different overload of Get in the implementation but the Of B is trying to contrain it to B for some reason.

Multiple "default" properties/methods in a VB6 class?

I am trying to make a replacement VB6 class for the Scripting.Dictionary class from SCRRUN.DLL. Scripting.Dictionary has (among other things) a "Keys" method that returns an array of keys, and a read/write "Item" property that returns the item associated with a key. I am confused about this, because both of them seem to be defaults for the class. That is:
For Each X In MyDict
Is equivalent to:
For Each X In MyDict.Keys
Which to me implies that "Keys" is the default operation for the class, but:
MyDict("MyKey") = "MyValue"
MsgBox MyDict("MyKey")
Is equivalent to:
MyDict.Item("MyKey") = "MyValue"
MsgBox MyDict.Item("MyKey")
Which to me implies that "Item" is the default operation for the class.
I've never before created a VB6 class that had a default operation, so upon realizing this, I thought perhaps I could define multiple default operations as long as they all have different signatures, which they do: Keys is nullary, the Item getter takes a Variant, and the Item setter takes two Variants. But this doesn't seem to be allowed: When I use "Tools/Procedure Attributes" to set the Keys function to be the default, and then I use it to set the Item property to be the default, the IDE complains that a default has already been set.
So I think I'm misunderstanding something fundamental here. What is going on in the Scripting.Dictionary object that makes it able to act as if "Keys" is the default in some contexts, but as if "Item" is the default in others? And whatever it is, can I accomplish the same thing in VB6?
OK, answering my own question: I haven't tried this yet, but I gather that "Item" should be made the default, and that I should add an entirely new function called "NewEnum" that looks something like the following (slightly modified from an example in Francesco Balena's "Programming Microsoft Visual Basic 6.0" book):
Public Function NewEnum() As IUnknown
Set NewEnum = m_Keys.[_NewEnum]
End Function
(where "m_Keys" is a Collection containing the keys), and then use Tools/Procedure Attributes to hide NewEnum and to set its ProcID to -4.
What you are observing is the difference between the default member and a collection enumerator. A COM object (including VB6 classes) can have both.
You can identify the default property of a class by looking in the Object Browser for the tiny blue globe or the words "default member of" in the description (see Contents of the Object Browser). The Object Browser will not identify an enumerator method, but if you look at the class's interface definition using OLE View or TypeLib Browser (free but registration required) it's DispId will be 0xfffffffc or -4.
In your own class, you can mark the default property by setting the Procedure ID to "(default)" in the Procedure Attributes dialog (see Making a Property or Method the Default). You already listed the steps for setting up the collection enumerator in your own answer, but you can find this listed as well in the Programmer's Guide topic Creating Your Own Collection Class: The House of Bricks.
Scripting.Dictionary has a dirty secret:
It does not handle enumeration at all, it returns big ugly Variant arrays and your For Each loops iterate over those.
This is one of the reasons why a Dictionary can actually be far less efficient than a standard VB6 Collection.

EF4: The closed type 'xxxx' does not have a corresponding element settable property

I'm using this guide to call stored procedure in my projet which using EF4 EDMX through WCFDataservice.
I have mapped a complex type to return items from the stored procedure. If I call the method by http, the XML'result is perfect, but when I call with this code:
public void Test()
{
Uri methodUri = new Uri(entities.BaseUri + "/GetCase");
List<CaseFiltered> result = entities.Execute<CaseFiltered>(methodUri).ToList();
}
I get this exception The closed type CaseFiltered does not have a corresponding element settable property.
I had try this solution but it doesn't work for me.
Have you a solution?
Thank you!
Ok I find the solution according this article
Actually, you did everything
right...However, our client library
does not support materialization of a
collection of complex types directly
(yet). If you look at the output of
the service op, you would see a list
of tag, rather than an Atom
Feed.
My workaround: I'm using Case entities, not the CaseFiltered complex type

Resources