How xpath works internally? - java

When I Write a XPath then from where does the browser fetch the XML of page,In short how browser works internally with xpath.
I am learning selenium and I am using xpath to identify WebElements.

In general, an XPath expression specifies a pattern that selects a set of XML nodes. XSLT templates then use those patterns when applying transformations.
(XPointer, on the other hand, adds mechanisms for defining a point or a range so that XPath expressions can be used for addressing).
The nodes in an XPath expression refer to more than just elements. They also refer to text and attributes, among other things. In fact, the XPath specification defines an abstract document model.
For more you can refer this link : How xpath works internally

In general an XPath processor takes as input (a) an XPath expression, and (b) a node used as the context node; it evaluates that expression against that context node, and returns a result to the calling application.
So an API for invoking XPath will generally look like
result = xpath.eval(expression, contextNode)
or perhaps
result = contextNode.evalXPath(expression)
or perhaps
result = xpath.compile(expression).eval(contextNode)
In a web browser environment the contextNode might implicitly be set to the HTML page by default.
In practice APIs for invoking XPath have additional complexities, for example to allow the namespace context to be set, and to allow external variables/parameters to be bound to values.

Related

Jayway JSONPath: how to select terminal nodes

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.

XPath to check the namespace a prefix is bound to

Say I have the following XML file:
<a xmlns:foo="http://foo"></a>
I need to check whether the prefix foo is bound to http://foo or not. Whereby not bound could indicate that the said prefix does not exist at all or is bound to some other namespace URI.
I already have a library that takes a Document object and an XPath expression and returns a (possibly empty) List of Nodes that exist at that XPath.
So what would be an expression that would check for the presence of a prefix foo in the top-most element (document element) bound to the namespace http://foo and that would yield one node for the above XML and zero nodes for the following XMLs:
<a xmlns:fooX="http://foo"></a>
and
< xmlns:foo="http://fooX"></a>
I tried, as a first step, to just get the value of that attribute using:
/*[#*[local-name()='foo']]
... but it seems that prefix-binding attributes are handled differently from "normal" attributes.
If you want to do it with XPath then you have to use the namespace axis: /*[namespace::foo[. = 'http://foo']]. DOM Level 3 might provide different ways treating the namespace declarations as attributes and resolving prefixes, see http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI.

XPath with custom value for operand instead of xml

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/

XPath, Java and serialized xml

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.

XJC - Generate xml using Xpath

After converting XSD to java objects using XJC , I would like to generate an xml file giving xpath and value to the xpath.
Examples.
Say I'm giving xpath and the value as
customer/name = XXXXX_VALUE
It should assign internally to the generated objects ... CustomerType.setName() ..
An XML also should generate as expected following the Xpath rule.
I know in Castor we can do this using ClassDescripor and FieldDescriptor. But I would like to know how to do this using XJC
JXPath can be used to navigate javabeans via something similar to xpaths.
http://commons.apache.org/proper/commons-jxpath/
Specifically, when you supply a factory you can create objects. There are several situations that are not supported nativly, but with a little bit of thought you can implement your own extension of createPathAndSetValue that can deal with your specific predicate logic.
http://commons.apache.org/proper/commons-jxpath/users-guide.html#Creating_Objects

Categories

Resources