XML.orgXML.org
FOCUS AREAS |XML-DEV |XML.org DAILY NEWSLINK |REGISTRY |RESOURCES |ABOUT
OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index]
Re: [xml-dev] An XML API using Java streams

(1) I believe that your investigation is very much worth pursuing! It could be labelled "A streaming API for XML navigation and construction", yes? Important aspects that occur to me are, first of all, the prospect of describing navigation in a functional way, using side-effect free expressions; and also the possibility to obtain navigation results as streams, creating a composability that conventional APIs lack.

(2) A great challenge - and perhaps a hopeless one - would be to create an expressiveness which could at least be a far cry of what XPath offers. It is strange to say
     N.walk(Axis.child("city")).flatMap(Axis.attribute("name").map(Node::stringValue)
when what you really want to say is
     city/@name

So what would be the goals and non-goals of the new API? Where will "Simplicity, naturalness and intuitiveness" appear?

(3) I do not think that an embedded expression language is per se inferior to using Java primitives. In fact, it can be an incomparably better choice. Proof: nobody would consider replacing regular expressions by calls to a Java-native "API for string navigation" (streaming or not).

(4) I think the streaming API you envisage would be a dedicated low-level API. Overdue! What we need, apart from that, is a really high-level API based on XPath and XQuery - where "really high-level" means to combine the full power of XPath/XQuery with a seamless integration into Java: the Java code supplies and receives exactly the types it is comfortable with, rather than translating between XDM representations and familiar types.

Hans-Jürgen


Michael Kay <mike@saxonica.com> schrieb am 10:51 Dienstag, 20.Juni 2017:


I'm struck how 95% of Java/XML users still seem to be stuck on DOM navigation, perhaps with a bit of XPath thrown in, which all seems a terribly late-20th-century way of doing things. The success of jQuery in the _javascript_ world, and the emergence of the Java Streams API, suggests there ought to be a better way. I don't know if anyone has done this before, but I thought I'd sketch out some ideas. (I have to say me experience with the Streams API is pretty cursory, to coin a phrase, so there may well be better ways of doing things that I've missed.

In particular:

(a) It would be nice to navigate using functional stream-based interfaces rather than procedural step-by-step navigation

(b) It would be nice to do all the navigation using Java primitives without requiring XPath as a separate interpreted sub-language.

Navigation is basically a question of constructing streams of nodes. Let's start by defining the XPath axes as functions (Node -> Stream(Node)). For example, given a node N, Axis.child(N) returns a stream containing the children of N.

If we define Node.walk(F) as returning a stream that navigates using the supplied function F, then

N.walk(Axis::child)

gets the children of N (you could write Axis.child(N) if you prefer), while

N.walk(Axis::child).flatMap(Axis::child)

gets the grandchildren.

If we define NodeTest::isElement as a function that returns true if the argument is an element node, then

N.walk(Axis::child).filter(NodeTest::isElement)

returns a stream of child nodes that are elements.

If we want to match nodes with a specific local name, then NodeTest.withLocalName(String) returns a function that returns true for nodes having that local name, so we can write

N.walk(Axis::child).filter(NodeTest.withLocalName("city"))

This is getting a bit long-winded for a simple task, so perhaps Axis.child(N) should return a function that navigates the child axis and filters by name, so the above becomes

N.walk(Axis.child("city"))

If Node.stringValue() returns the string value of a node

N.walk(Axis.child("city")).flatMap(Axis.attribute("name").map(Node::stringValue)

returns the names of the child cities (as a Stream<String>).

Perhaps there's a shortcut for this:

N.walk(Axis.child("city")).map(Axis.attValue("name"))

And then we could add tree construction using function chaining, e.g.

element("cities")
  .addChild(element("city").addAttribute("name", "Rome"))
  .addChild(element("city").addAttribute("name", "Paris"))

=====

Just an initial sketch of some ideas. Does it seem worth pursuing?

Michael Kay
Saxonica
_______________________________________________________________________

XML-DEV is a publicly archived, unmoderated list hosted by OASIS
to support XML implementation and development. To minimize
spam in the archives, you must subscribe before posting.

[Un]Subscribe/change address: http://www.oasis-open.org/mlmanage/




[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index]


News | XML in Industry | Calendar | XML Registry
Marketplace | Resources | MyXML.org | Sponsors | Privacy Statement

Copyright 1993-2007 XML.org. This site is hosted by OASIS