How to handle Dynamic xpath in Groovy? - xpath

in the below example the xpath had been in given in the code.
String xml = Recall.getXml()
def telephoneNumbers = new XmlSlurper().parseText(xml)​​​​​​​​
def outputBuilder = new groovy.xml.StreamingMarkupBuilder()
String telephoneXml = outputBuilder.bind { mkp.yield telephoneNumbers.telephone }
would like to know any possible solution to specify the same xpath through a variable. like below.
String telephoneXml = outputBuilder.bind { mkp.yield ${xpath} }
Thanks in advance.

to be clear this is not xpath. in groovy it's named gpath, and it's a groovy expression.
You can use Eval class to evaluate groovy expression from string:
def xml = '''<root>
<telephone>1234567899</telephone>
<cell>1234567890</cell>
</root>'''
def telephoneNumbers=new XmlSlurper().parseText(xml)
def outputBuilder = new groovy.xml.StreamingMarkupBuilder()
def gpath = "xml.telephone"
String telephoneXml = outputBuilder.bind { mkp.yield Eval.me('xml',telephoneNumbers,gpath) }

Related

How to pass complex types as arguments in graphene Python

I'm trying to create a query that accepts a complex argument object like so:
class Pair(graphene.ObjectType):
x = graphene.Int()
y = graphene.Int()
class Pairs(graphene.ObjectType):
pairs = graphene.List(graphene.NonNull(graphene.Field(Pair, required=True)), required=True)
class Query(graphene.ObjectType):
endpoint = graphene.Field(ResultType, pairs=graphene.Argument(Pairs, required=True))
I'm invoking it as follows in testing:
client = graphene.test.Client(graphene.Schema(query=Query))
executed = client.execute(
"""query($pairs: Pairs!) {
endpoint(pairs: $pairs) {
[result type goes here]
}
}"""
Any thoughts on what may be wrong with this approach?
I was able to do with the code below
class SomeFilter(graphene.InputObjectType):
name = graphene.String()
class Query(graphene.ObjectType):
all_somes = graphene.List(Some, options=SomeFilter())
def resolve_all_somes(self, info, options=None):
if options:
if name := options.get('name'):

Is there a Groovier way to access properties file?

One can access properties file like that:
def props = new Properties()
new File('my.props').withInputStream { props.load(it) }
assert props.foo == 'bar'
I think that's quite cumbersome. Isn't there a groovier way?
// does not compile
def props = Properties.from(new File('my.props'))
assert props.foo == 'bar'
I believe the answer is no.
The doc for Groovy JDK enhancements does not contain java.util.Properties (compared to, say, java.io.File). This article implies prior art for a home-grown solution.
You can always utilize metaprogramming:
Properties.metaClass.static.from = { File f ->
def p = new Properties()
f.withInputStream { p.load(it) }
p
}
p = Properties.from(new File('a.properties'))
assert p['a'] == '10'
I'm not aware of any shortcut to create a properties from a file. I'd like to suggest a simple solution without prior variable declaration:
p = new File('my.props').withReader { reader ->
new Properties().with {
load reader
it
}
}

Array of annotations as parameter to an annotation, in Scala

There are plenty of questions about passing an array as a parameter to an annotation, this is not a dupe of those.
I would like to use a Java-land annotation that takes an array of annotations as a parameter, e.g.
#ManagedOperation
#ManagedOperationParameters({
#ManagedOperationParameter(name="start"),
#ManagedOperationParameter(name="end")
})
def stuff(start: String, end: String): Unit = ???
But this is not valid syntax in Scala, nor is
#ManagedOperation
#ManagedOperationParameters(Array(
#ManagedOperationParameter(name="start"),
#ManagedOperationParameter(name="end")
))
def stuff(start: String, end: String): Unit = ???
so what is the correct way to do this, if it is even possible?
BTW, I even checked all of github to see if any Scala devs are using this (Spring JMX) annotation.
In scala the inner annotation should be used as regular type:
#JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "moduleType",
defaultImpl = classOf[PuppetModule]
)
#JsonSubTypes(Array(
new Type(value = classOf[PuppetModule], name = "puppet"),
new Type(value = classOf[PluginModule], name = "plugin")
))
trait Module {
val moduleType: String = if (this.isInstanceOf[PuppetModule]) "puppet" else "plugin"
val nodes: List[String] = List[String]()
}

Ruby map JSON into Ruby Class -Can't convert string to Integer

New to JSON/RUBY.
I have a Rest Service returning a JSON string and I would like to parse this into a Ruby Class. Is this recommended? I have tried the following example and get error- Can't convert String to Integer. This is for a rhomobile app I'm working on. I'm thinking POJO-->JSON-->Ruby. Any advice would be appreciated.
Ruby
##get_result = #params['body']
puts "##get_result : #{##get_result}"
data2 =##get_result
cust1 = data2["PolicyList"].map { |rd| PolicyList.new(rd["policyNbr"], rd["systemId"], rd["insuredName"],
rd["type"], rd["statusCd"], rd["statusDes"], rd["payorZipcode"],
rd["lastPaymentDate"], rd[lastPaymentAmount], rd["pastDueDate"], rd["pastDueAmount"],
rd["currentDueDate"], rd["currentDueAmount"], rd["eft"],
rd["suspenseAmt"], rd["expireTime"]) }
Class
class PolicyList
attr_accessor :policyNbr, :systemId, :insuredName,
:type, :statusCd, :statusDes, :payorZipcode,
:lastPaymentDate,:lastPaymentAmount,:pastDueDate,
:pastDueAmount,:currentDueDate,:currentDueAmount,:eft,
:suspenseAmt,:expireTime
def initialize(policyNbr, systemId,insuredName,type,statusCd,statusDes,payorZipcode,lastPaymentDate,lastPaymentAmount,
pastDueDate,pastDueAmount,currentDueDate,currentDueAmount,eft,suspenseAmt,expireTime)
#systemId = systemId
#insuredName = insuredName
#type = type
#statusCd = statusCd
#statusDes = statusDes
#payorZipcode = payorZipcode
#lastPaymentDate = lastPaymentDate
#lastPaymentAmount = lastPaymentAmount
#pastDueDate = pastDueDate
#pastDueAmount = pastDueAmount
#currentDueDate = currentDueDate
#currentDueAmount = currentDueAmount
#eft = eft
#suspenseAmt = suspenseAmt
#expireTime = expireTime
end
end
Returned JSON
[{"policyNbr":"0000001","systemId":"MB","insuredName":"JOHN DOE ","type":"MEMBERSHIP","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"07/12/2012","lastPaymentAmount":25.00,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":1362152384971},{"policyNbr":"0000002","systemId":"PC","insuredName":"JOHN DOE","type":"AUTO","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"02/15/2013","lastPaymentAmount":308.50,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":0},{"policyNbr":"0000003","systemId":"PC","insuredName":"JOHN DOE","type":"HOME","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"09/05/2012","lastPaymentAmount":149.00,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":0}]
You're getting an array of PolicyList objects, but there is no key called 'PolicyList'. I think you need this:
cust1 = data2.map { |rd| PolicyList.new(rd["policyNbr"], rd["systemId"], rd["insuredName"],
rd["type"], rd["statusCd"], rd["statusDes"], rd["payorZipcode"],
rd["lastPaymentDate"], rd['lastPaymentAmount'], rd["pastDueDate"], rd["pastDueAmount"],
rd["currentDueDate"], rd["currentDueAmount"], rd["eft"],
rd["suspenseAmt"], rd["expireTime"]) }
To make it easier for you. Here is a complete example.
class PolicyList
attr_accessor :policyNbr, :systemId, :insuredName,
:type, :statusCd, :statusDes, :payorZipcode,
:lastPaymentDate,:lastPaymentAmount,:pastDueDate,
:pastDueAmount,:currentDueDate,:currentDueAmount,:eft,
:suspenseAmt,:expireTime
def initialize(policyNbr, systemId,insuredName,type,statusCd,statusDes,payorZipcode,lastPaymentDate,lastPaymentAmount,
pastDueDate,pastDueAmount,currentDueDate,currentDueAmount,eft,suspenseAmt,expireTime)
#systemId = systemId
#insuredName = insuredName
#type = type
#statusCd = statusCd
#statusDes = statusDes
#payorZipcode = payorZipcode
#lastPaymentDate = lastPaymentDate
#lastPaymentAmount = lastPaymentAmount
#pastDueDate = pastDueDate
#pastDueAmount = pastDueAmount
#currentDueDate = currentDueDate
#currentDueAmount = currentDueAmount
#eft = eft
#suspenseAmt = suspenseAmt
#expireTime = expireTime
end
end
require 'json'
json = <<-JSON
[{"policyNbr":"0000001","systemId":"MB","insuredName":"JOHN DOE ","type":"MEMBERSHIP","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"07/12/2012","lastPaymentAmount":25.00,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":1362152384971},{"policyNbr":"0000002","systemId":"PC","insuredName":"JOHN DOE","type":"AUTO","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"02/15/2013","lastPaymentAmount":308.50,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":0},{"policyNbr":"0000003","systemId":"PC","insuredName":"JOHN DOE","type":"HOME","statusCd":"01","statusDes":"PAID","payorZipcode":"99999","lastPaymentDate":"09/05/2012","lastPaymentAmount":149.00,"pastDueDate":"","pastDueAmount":0.00,"currentDueDate":"","currentDueAmount":0.00,"eft":false,"suspenseAmt":false,"expireTime":0}]
JSON
##get_result = JSON.parse(json)
puts "##get_result : #{##get_result}\n\n"
data2 =##get_result
cust1 = data2.map { |rd| PolicyList.new(rd["policyNbr"], rd["systemId"], rd["insuredName"],
rd["type"], rd["statusCd"], rd["statusDes"], rd["payorZipcode"],
rd["lastPaymentDate"], rd['lastPaymentAmount'], rd["pastDueDate"], rd["pastDueAmount"],
rd["currentDueDate"], rd["currentDueAmount"], rd["eft"],
rd["suspenseAmt"], rd["expireTime"]) }
puts cust1.inspect

How to dynamically add OR operator to WHERE clause in LINQ

I have a variable size array of strings, and I am trying to programatically loop through the array and match all the rows in a table where the column "Tags" contains at least one of the strings in the array. Here is some pseudo code:
IQueryable<Songs> allSongMatches = musicDb.Songs; // all rows in the table
I can easily query this table filtering on a fixed set of strings, like this:
allSongMatches=allSongMatches.Where(SongsVar => SongsVar.Tags.Contains("foo1") || SongsVar.Tags.Contains("foo2") || SongsVar.Tags.Contains("foo3"));
However, this does not work (I get the following error: "A lambda expression with a statement body cannot be converted to an expression tree")
allSongMatches = allSongMatches.Where(SongsVar =>
{
bool retVal = false;
foreach(string str in strArray)
{
retVal = retVal || SongsVar.Tags.Contains(str);
}
return retVal;
});
Can anybody show me the correct strategy to accomplish this? I am still new to the world of LINQ :-)
You can use the PredicateBuilder class:
var searchPredicate = PredicateBuilder.False<Songs>();
foreach(string str in strArray)
{
var closureVariable = str; // See the link below for the reason
searchPredicate =
searchPredicate.Or(SongsVar => SongsVar.Tags.Contains(closureVariable));
}
var allSongMatches = db.Songs.Where(searchPredicate);
LinqToSql strange behaviour
I recently created an extension method for creating string searches that also allows for OR searches. Blogged about here
I also created it as a nuget package that you can install:
http://www.nuget.org/packages/NinjaNye.SearchExtensions/
Once installed you will be able to do the following
var result = db.Songs.Search(s => s.Tags, strArray);
If you want to create your own version to allow the above, you will need to do the following:
public static class QueryableExtensions
{
public static IQueryable<T> Search<T>(this IQueryable<T> source, Expression<Func<T, string>> stringProperty, params string[] searchTerms)
{
if (!searchTerms.Any())
{
return source;
}
Expression orExpression = null;
foreach (var searchTerm in searchTerms)
{
//Create expression to represent x.[property].Contains(searchTerm)
var searchTermExpression = Expression.Constant(searchTerm);
var containsExpression = BuildContainsExpression(stringProperty, searchTermExpression);
orExpression = BuildOrExpression(orExpression, containsExpression);
}
var completeExpression = Expression.Lambda<Func<T, bool>>(orExpression, stringProperty.Parameters);
return source.Where(completeExpression);
}
private static Expression BuildOrExpression(Expression existingExpression, Expression expressionToAdd)
{
if (existingExpression == null)
{
return expressionToAdd;
}
//Build 'OR' expression for each property
return Expression.OrElse(existingExpression, expressionToAdd);
}
}
Alternatively, take a look at the github project for NinjaNye.SearchExtensions as this has other options and has been refactored somewhat to allow other combinations
There is another, somewhat easier method that will accomplish this. ScottGu's blog details a dynamic linq library that I've found very helpful in the past. Essentially, it generates the query from a string you pass in. Here's a sample of the code you'd write:
Dim Northwind As New NorthwindDataContext
Dim query = Northwind.Products _
.Where("CategoryID=2 AND UnitPrice>3") _
.OrderBy("SupplierId")
Gridview1.DataSource = query
Gridview1.DataBind()
More info can be found at scottgu's blog here.
Either build an Expression<T> yourself, or look at a different route.
Assuming possibleTags is a collection of tags, you can make use of a closure and a join to find matches. This should find any songs with at least one tag in possibleTags:
allSongMatches = allSongMatches.Where(s => (select t from s.Tags
join tt from possibleTags
on t == tt
select t).Count() > 0)

Resources