The problem I'm trying to solve is the clumbsiness of accessing properties, or name/value pairs,
in particular when serialized to a kind of properties file.
With the advent of the xproperties command, you can now read a standard Java properties file (in either text or xml form) and assign it to a variable.
Suppose you have a simple properties file
a=b
This parses into XML (using the standard Java Properties API) as
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd" []><properties version="1.0"><entry key="a">b</entry></properties>
Read into a variable as
props=$<(xproperties -in file.properties)
You can access the value of key "a" with the expression
<[ $props/properties/entry[key="a"]/string() ]>
Am I the only one who finds this extremely cumbersome ?
I would like to do something like one of these
$props.a
$props[a]
$props["a"]
or even
${props:"a"}
But any of these syntax sugars requires the shell "know" the structure of $props and do something magic with it. I really dont like the idea of extending the core syntax to handle a particular schema, even one as common as Java Properties. Suppose for example I wanted Map instead so I could put non-string values ... Properties wont cut it.
MarkLogic has a xquery function for that (map:map()) and various map:* methods to get at the values. I'd like something like this but built into the shell and expandable to arbitrary XML schemas. What to do ?
The latest thought I had was to borrow somethign from Perl (gasp). The tie funciton. "Bind" a variable to an expression so that you could define your own shortcuts with map or array-like syntax.
Suppose for example I could do something like
xbind props '<[ //entry[key=$key]/string() ]>'
then magically make
$props["a"] or maybe ${props:a} or ${props[a] } invoke the bound expression and produce "b"
You could then use this mechanism to create array or map-like notation out of ANY schema.
Is this worth the effort ? When does adding syntax actually start to deter from a language instead of add to it ?
I settled for the tie operator.
ReplyDeletetie variable 'expression'
The expression is invoked as an xquery expression when variable is referenced via
${var:args}
The args are passed as $_ and the variable is the context for the expression.
Example using xproperties
A=$<( xproperties -a foo="foo value" -a bar="bar value" -a a.b="a.b value")
tie A './/entry[@key = $_ ]/string()'
echo ${A:foo}