I'm using Jayway JSONPath.
Given a JSON document having nodes with the same name at different structure levels, how would I select only those nodes that are terminal nodes, i.e. having only text or no content?
XPath would allow not(child::*) as a predicate, but I can't see a JSONPath equivalent.
Unfortunately, no JSONPath implementation (as of now) offers such an operation. However, some of the more advanced implementations that expanded on Goessner's reference have operations that get close to this.
One workaround is to use check the type of a node, if possible. For instance this is possible in the JavaScript JSONPath-Plus implementation using Type selectors for JSON types: e.g. #null(), #boolean(), #number(), #string(), #array(), #object()
#integer() and others. This allow us for instance to get only numeric values:
$..*#number()
Combined with a more meaningful path selection we might get close. Nonetheless, this will not yield terminal values only but at least avoids array and object type properties.
Another workaround that is should work with basic data types is to use the regex matcher available in quite a few implementations (like JayWays, many JavaScript implementations, etc) to interpret the type of a node, e.g. again let's say numeric values
$..[?(#.price =~ /[0-9]+\.?[0-9]*/)]
Again, this will not give you terminal values only but avoids array and object type properties.
Related
Probably, this is a duplicated question, but I cannot find the question I want to read, so I posted here.
I'm newbie of Antlr, and I try to use Antlr4 to make abstract syntax tree with visitor pattern in Scala.
However, I cannot come up with how to put together results of multiple rules like below into one list.
foo: (rule0 | rule1)*
rule0: ...
rule1: ...
I know there is a way to get each lists (i.e. list of rule0s and list of rule1s).
However, that way probably breaks the order of occurrence (I want to maintain the order).
The way like rules=(rule0 | rule1)* is not also allowed, so I cannot write like below
ctx.rules().asScala.map(...).toArray`
My question is how to put together into list of multiple rule results while maintaining order of appearance in visitor pattern.
The visitor is just a walker over the parse tree generated by your parse run. The visitor class iterates over the children of each parser context and calls the visitor functions. That means the actual information is stored in the parse tree and you can use it directly.
When you get a FooContext iterate over its children list, which contains the found Rule0Context and Rule1Context instances in the order they were used in the source code. This gives you both, the positional information about sub parts as well as the info about each of the sub parts.
I have an object containing cyclic references. According to the XStream Json documentation, cyclic references are NOT supported, and one should therefore use the NO_REFERENCES XStream mode when marshalling an object to Json:
What limitations has XStream's JSON support?
JSON represents a very simple data model for easy data transfer.
Especially it has no equivalent for XML attributes. Those are written
with a leading "#" character, but this is not always possible without
violating the syntax (e.g. for array types). Those may silently
dropped (and makes it therefore difficult to implement
deserialization). References are another issue in the serialized
object graph, since JSON has no possibility to express such a
construct. You should therefore always set the NO_REFERENCES mode of
XStream. Additionally you cannot use implicit collections, since the
properties in a JSON object must have unique names.
But I tried setting the mode to ID_REFERENCES and it appears as though the Object is marshalled with references, and the object can be unmarshalled properly. Is the XStream documentation simply outdated, or have I simply inadvertently created the object graph in such a way that I haven't hit any of the limitations?
Sorry, but I can't post my exact graph as an example as it contains application/domain-specific code and it might take some time to construct a 'clean' alternative.
Java program takes a long list of inputs(parameters), churns a bit and spits some output.
I need a way to organize these parameters in a sane way so in the input txt file I want to write them like this:
parameter1 = 12
parameter2 = 10
strategy1.parameter1 = "goofy"
strategy2.parameter4 = 100.0
Then read this txt file, turn it into a Java object I can pass around to objects when I instantiate them.
I now pyqtgraph has ParameterTree which is handy to use; is there something similar in Java? I am sure others must have had the same need so I don't want to reinvent the wheel.
(other tree structures would also be fine, of course, I just wanted something easy to read)
One way is to turn input.txt into input.json:
{
"parameter1": 12,
"parameter2": 10,
"strategy1": {
"parameter1": "goofy"
},
"strategy2": {
"parameter4": 100.0
}
}
Then use Jackson to deserialize input.json into one of these:
A Map<String, Object> instance, which you could navigate in depth to get all your parameters
An instance of some class of your own that mimics input.json's structure, where your parameters would reside
A JsonNode instance that would be the root of the tree
(1) has the advantage that it's easy and you don't have to create any class to read the parameters, however you'd need to traverse the map, downcast the values you get from it, and you'd need to know the keys in advance (keys match json object's attribute names).
(2) has the advantage that everything would be correctly typed upon deserialization; no need to downcast anything, since every type would be a field of your own classes which represent the structure of the parameters. However, if the structure of your input.json file changed, you would need to change the structure of your classes as well.
(3) is the most flexible of all, and I believe it's the option that is closest to what you have in mind, nonetheless is the most tedious to work with, since it's too low-level. Please refer to this article for further details.
Is there is possibility of perform xpath eval with custom value instead of having xml.
Example:
count(/departmemt/employees) > 10
Here, i will provide the values for /department/employee and i want to use xpath libraray in java to take care of doing the evaluation.
It is something like the user exposed method, String getValue (String operand)...
here getValue method should get called from xpathEngine and i will take care of providing the value for each operand.
Please help me if there is any possibility of doing this.
Thanks
Durai
For use XPath-like structures in java can be used commons-jxpath
http://commons.apache.org/proper/commons-jxpath/
Assuming some xml like
<foo>
<bar>test</bar>
</foo>
Evaluating an expression with returnType = String like
/foo/bar
will return "test". However, I'd like to get the serialized xml instead, so something like
<bar>test</bar>
should be returned instead. As I can not check for the returnType in java's xpath implementation (xerces), I cannot simply get an object as result and if it indeed is a node, convert it to serialized xml.
Note: I don't know whether the expression will actually return a node, a string, a number or whatever so I cannot provide an appropriate return type to the eval function except string which, as my problem states, returns the text content and not the serialized xml.
So I am curious -> is there either a java- or (preferred) a xpath-way (function?) to get serialized xml for type string instead of the text children of the selected node?
thanks!
Alex
use the xpath return type XPathConstants.NODE and then you can serialize the returned Node yourself.
Now, you are right to observe that it's difficult to discover the return type of the result; this is a real design weakness of JAXP.
If it's a problem to you, consider using Saxon's s9api interface, which returns XdmValue objects whose type you can interrogate; you also get XPath 2.0 access as a bonus.
As Michael Kay answered, this is difficult in JAXP (the native Java interface).
In Mr Kay's Saxon library's s9api API (see Evaluating XPath Expressions using s9api), once you've called XPathSelector.evaluate() or XPathSelector.evaluateSingle() you can get the XML serialisation by calling XdmValue.toString().
However, if the XPath selected an attribute (e.g. //#name) you will still get the XML serialisation, e.g. name="value". You can call XdmItem.getStringValue(), but for elements that method will return the same values you're already seeing - the textual content of the element, not the serialisation. I've posted separately about how to distinguish between attributes and elements returned from Saxon s9api.