I need to get the values from a DOM object using Java, I would like to know the differences between XPath & JXPath.
XPath is a W3C-defined language for finding data within XML documents. There are many implementations. The latest version is XPath 3.1, but many implementations only support the original version 1.0.
JXPath is an open-source library that implements (some version of?) the XPath language, applying it specifically to navigation of an XML view of a general graph of Java objects, rather than an XML document per se.
Related
We are using Saxon, calling it from Java, to perform queries. When we upgrade to XPath 3.1, will it handle all queries written for XPath 2.0 the same as before? Or are there changes in what is returned for some queries?
I'm asking because if it's 100% upwardly compatible, we just change our existing XPath 2.0 code to use XPath 3.1. But if it's different, then we need to add XPath 3.1 as a new datasource type.
We do have XPath 1.0 as a distinct datasource because there are differences between what XPath 1.0 and 2.0 return for some queries.
You can assure this premise by following this chain:
XPath-3.0 is backwards compatible to XPath-2.0
This appendix provides a summary of the areas of incompatibility between XPath 3.0 and [XML Path Language (XPath) Version 1.0]. In each of these cases, an XPath 3.0 processor is compatible with an XPath 2.0 processor.
XPath-3.1 is backwards compatible to XPath-3.0.
This Recommendation specifies XPath version 3.1, a fully compatible extension of XPath version 3.0.
XPath 3.1 allows new expressions for arrays, maps and functions so if you have a test suite checking for some syntax errors in XPath 2 expressions you might find they could be allowed in XPath 3.1 and don't give an error.
The main error I remember to be converted into legal syntax is foo/[bar] which constructs an array in XPath 3.1 in the last step.
I'm maintaining a legacy tool of the company I work for written in C# and I'm converting it to .Net standard 2.0. It uses the Saxon-HE processor to process some XPaths and replace some configurations in files.
Its NuGet package on .NET has dependencies that do not allow the execution on all the .Net standard 2.0 compliant platforms (in my case both .Net Framework and .Net core), so I need to replace it with one another tool, better if the standard .Net XPath library.
The problem is that the tool uses some XPaths that perform complex operations such as concatenate strings and select an array item, and I don't know if it's a Saxon-specific syntax or regards a standard.
It is important to know this because if the XPaths are compliant to some XPath standard I could find one another way to process the same XPaths.
Here is some examples:
First:
for $row in /Item/SubItem[*]/SubSubItem return(concat($row, \"/ConcatValue\"))
Second:
/Item/SubItem[*]/SubSubItem/(add[#key=\"TheKey\"]/#value/string(), '')[1]
Do you know something about this XPath syntax?
Thank you
The XPath expressions you have given as examples require an XPath 2.0 processor but they are not specific to Saxon.
The expression
for $row in /Item/SubItem[*]/SubSubItem return(concat($row, \"/ConcatValue\"))
is a ForExpression, which is specific to XPath 2.0, and is not easily converted to XPath 1.0 because its result is a sequence of strings, and there is no such data type in XPath 1.0.
The expression
/Item/SubItem[*]/SubSubItem/(add[#key=\"TheKey\"]/#value/string(), '')[1]
is specific to XPath 2.0 because it uses a parenthesized expression on the RHS of the "/" operator; and again, because it returns a sequence of strings.
I'm afraid I can't advise you whether there exist XPath 2.0 libraries that run on .NET Core, which I assume is your requirement. Saxon cannot be made to run on .NET Core because of its dependency on IKVM, which doesn't support that platform and which (I gather) cannot readily be adapted to do so.
Note that XPath 2.0 is a subset of XQuery 1.0, so you could extend your search to XQuery 1.0 processors as well as XPath 2.0 processors.
Thanks to this comment I was able to test XPath2.Net and now everything works. I needed to change only one type of XPath definition
This one:
/Item/SubItem[*]/SubSubItem/(add[#key=\"TheKey\"]/#value/string(), '')[1]
Changes to
/Item/SubItem[*]/SubSubItem/(add[#key=\"TheKey\"]/#value/string(.), '')[1]
Please note the additional dot argument of the string() function.
This is strange as it should not be require the dot; in fact, per standard
In the zero-argument version of the function, $arg defaults to the
context item. That is, calling fn:string() is equivalent to calling
fn:string(.)
but XPath2 complains with this error
{"The function 'string'/0 was not found in namespace 'http://www.w3.org/2003/11/xpath-functions'"}
UPDATE:
After updating the XPath2.Net library to version 1.0.8 the string() syntax works.
I've got some XML documents which conform to a known schema which include geometries in GML format.
I'm looking to perform validation on the XML using XSD and Schematron validation, but I'll need some way of performing spatial queries within the Xpath language (I presume via extension functions).
I was wondering if anyone is aware of a standard for implementation I can use, or indeed if someone has already done this - I've come up empty on google.
As an example (representative only, only attempting to demonstrate the xpath part of the question (which is the question really - the fact I'm aiming to use it in schematron is moot))
My XML:
<Things>
<Thing type="A">
<Geometry>...GML...</Geometry>
</Thing>
<Thing type="B">
<Geometry>...GML...</Geometry>
</Thing>
</Things>
Xpath to return things of type A which spatially intersect with things of type B (again, I'm making up a function extension namespace and a (pretty dumb) function to give an example of what I'm trying to accomplish):
/Things/Thing[#type='A' and geo:has-intersection(Geometry, /Things/Thing[#type='B']/Geometry)]
As this seems somewhere between development and GIS, I've cross posted on GIS and StackOverflow.
The EXPath Geo Module defines functions on simple OGC geometries. I believe there are several implementations but the only one I'm familiar with is BaseX.
I googled, but I can't find a satisfactory answer. This SO question is related but kinda old as well as the exact opposite of what I am looking for: a way to do screen-scraping using XPath, not CSS selectors.
I've used enlive for some basic screen-scraping but sometimes one needs the power of XPath selectors. So here it is:
Is there any equivalent to Nokogiri or lxml for clojure (java)? What is the state of the "pure java Nokogiri"? Any way to use the library from clojure? Any better alternatives than this hack?
There are a couple of possibilities here.
Several of these require semi-well formed XML to work. If you don't have it, I would pair clj-tagsoup with hiccup to produce the XML (parse with clj-tag-soup, which produces a form that hiccup and write out as XML) and work with that.
First, just use the native JDK capabilities. Assuming the document is well formed enough, try using clj-xpath which provides a wrapper around the native JDK parsing.
If that doesn't suffice, consider taking a more Clojure data structure based route. A simpler path could just use the output of TagSoup and a combination of maps, filters, and nths.
If you need something more advanced, consider using zippers to provide structure around the data, making it easier to manipulate. Use clojure.xml/parse and clojure.zip/xml-zip to produce the zipper, and go from there. An example can be found at http://techbehindtech.com/2010/06/25/parsing-xml-in-clojure/.
Using the native structures is my preferred route for anything complicated, as you can bring the full power of the language to bear.
If you provide a sample of why you need XPath, I can provide some sample code.
Currently, I'm writing something to do Unit testing for XSLT2 functions, the idea is very simple:
Create a custom-library.xsl, which contains some custom XSLT2 functions.
Create a data XML contains the test cases, as following XML Schema xslunit.xsd:
schema structure http://xml.bodz.net/schema/xslunit/xslunit.png
Run the test cases by transform it, using xslunit-xslt2.xsl, and get the test result html.
Now, the question is, there is function-call in the test cases, and I have to evaluate it in the XSLT (file xslunit-xslt2.xsl). But I can't find a way to evaluate an XPath.
Though, it may be easy to using some kind of Java extensions, but I really don't want to bring in another trouble. I hope everything can just work with-in XSLT2 only.
No, pure XSLT 2.0 does not have support do evaluate an XPath expression found in your XML data. Saxon 9 (in its commercial editions) however has an extension function: http://www.saxonica.com/documentation/extensions/functions/evaluate.xml. And AltovaXML Tools has a similar one: http://manual.altova.com/AltovaXML/altovaxmlcommunity/index.html?xextaltova_general.htm
Update a decade later: XSLT 3.0 has an instruction <xsl:evaluate> which evaluates an XPath expression supplied dynamically as a string.