Bug #5673
closed
ixsl:set-property and URLs in property names
Applies to JS Branch:
2, Trunk
Fix Committed on JS Branch:
2, Trunk
Company:
Martynas Jusevičius
Description
This is another manifestation of #5031. How do I set a property which is a QName with a URL in it? I need to construct the following:
SaxonJS.transform({
"stylesheetParams": { "Q{https://www.w3.org/ns/ldt#}base": baseUri }
});
so I'm doing this:
<xsl:variable name="stylesheet-params" select="ldh:new-object()"/>
<ixsl:set-property name="Q{{https://www.w3.org/ns/ldt#}}base" select="$ldt:base" object="$stylesheet-params"/>
but of course I get an error:
Encountered null or undefined in path to nested object for ixsl:set-property: 'Q{https://www.w3'
If you will not consider removing special meaning of .
in ixsl:set-property/@name (I get it's problematic due to backwards compatibility), can we at least get an option where this behavior is disabled? Because in situations like this it's a PITA.
Also welcoming suggestions for a workaround :)
Worked around like this:
<xsl:variable name="js-statement" as="element()">
<root statement="{{ "Q{{&ldt;}}base": "{$ldt:base}" }}"/>
</xsl:variable>
<xsl:variable name="stylesheet-params" select="ixsl:eval(string($js-statement/@statement))"/>
Can you help me understand what's motivating this example?
If stylesheet-params
was an ordinary XPath map, you could just use XSLT functions or instructions to change it. Instead, you appear to have constructed a plain-old-JavaScript object on which you want to set a key named "Q{https://www.w3.org/ns/ldt#}base
" (do I have that right)?
What are you subsequently going to do with stylesheet-params
that requires it to be a JavaScript object not an XPath map?
I'm passing the $stylesheet-params
map to a JS listener function which ten passes it to SaxonJS.transform({ "stylesheetParams": { stylesheetParams });
.
In general I think it's a problem that properties with dots in their names cannot be used with ixsl:set-property/@name
, because there certainly are situations where this is required and escaping with a different char is not an option. In my case most of such propertes are URLs.
I agree the uncontrolled interpolation of "."s is a problem. I've imagined a lexical hack to work around it, but I'm waiting to see if my colleagues react in horror :-)
Basically, I'm thinking that if you said name="[a.b.c]"
we'd use the property name inside the square brackets without interpolating the dots. That, alas, wouldn't help if the name of the property you wanted to set was literally "[a.b.c]
" so it's still imperfect.
Perhaps
name="`a.b.c`"
allowing a backtick within the property name to be escaped as a double-back-tick?
Yes, that works for me.
name="a.b.c" ==> $object["a"]["b"]["c"]
name="`a.b.c`" ==> $object["a.b.c"]
name="`a``b.c`" ==> $object["a`b.c"]
Mismatched flavors of backtick would be errors or just produce whatever results they produce.
- Status changed from New to Resolved
- Applies to JS Branch Trunk added
- Fix Committed on JS Branch 2, Trunk added
Any "." that appears in a (region of) the string that is delimited by back tick is not interpreted as a dividor. Use two back ticks in a row to get a back tick.
- Company set to Martynas Jusevičius
- Contact person set to Martynas Jusevičius
Does that mean a $variable with a property name will have to include
backticks? That’s also slightly awkward :)
On Wed, 7 Sep 2022 at 18.43, Saxonica Developer Community <
notifications@plan.io> wrote:
Saxonica Developer Community notifications@plan.io writes:
Does that mean a $variable with a property name will have to include
backticks? That’s also slightly awkward :)
I’m not exactly sure what context you’re imagining. Today, the property
name is unconditionally split on dots. So the name “a.b.c” (whether it
comes from a literal or a variable, I believe) will be the equivalent of
$object["a"]["b"]["c"]
That’s a problem if the property name includes a period. If, for
example, you were trying to set the “a.b.c” property. With the fix I’ve
proposed, you could use “a.b.c
” and the dots inside the backtick
protected region wouldn’t be treated as separators.
How are you imagining that that would be different or more awkward if
the name was in a variable? What alternative would you suggest?
Be seeing you,
norm
--
Norm Tovey-Walsh
Saxonica
Ideally I’d like to pass the property name string as-is, without having to
modify it by escaping the dots (what I’m doing now) or wrap it into
backticks, as suggested here.
I guess I was imagining an extra attribute on the instruction as a flag
indicating how the dots are interpreted. But that would probably require
changing the SEF format?
I can live with the backticks :) I’ll be able to use URLs as properties now.
On Thu, 8 Sep 2022 at 12.35, Saxonica Developer Community <
notifications@plan.io> wrote:
Right. It was sort of a toss-up in my mind about which was better, a new attribute (which would have to have a new name, which would have to be exclusive of the existing attribute, which would require changes in both compilers, etc.) or some sort of lexical trick.
I was persuaded by the lexical technique partly because it was somewhat easier and simpler, but also because it's more versatile. A new attribute would be an all-or-nothing solution. The lexical approach means that you can be selective about which "."s are treated as dividers.
It did occur to me that we could have said that you can use "\." to escape the following period and "\\" to insert a literal backslash. But that would introduce questions about what backslash in front of other characters means and I backed slowly away from that idea.
Thanks Norm. I just want to make sure that I'm getting the new syntax right. Would it look like this?
<xsl:variable name="url" select="'https://saxonica.plan.io/issues/5673'" as="xs:string"/>
<ixsl:set-property name="{'`' || $url || '`'}" select="..." object="..."/>
Yes. If you're doing this in several places, you might get some milage out of a function:
<ixsl:set-property name="{f:escape-name($url)}" select="..." object="..."/>
for example
<xsl:function name="f:escape-name" as="xs:string">
<xsl:param name="name" as="xs:string"/>
<xsl:sequence select="'`'||replace($name, '`', '``')||'`'"/>
</xsl:function>
- Sprint/Milestone set to SaxonJS 2.5
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in JS Release set to SaxonJS 2.5
See also #5714 for documentation fixes to be applied.
Please register to edit this issue
Also available in: Atom
PDF
Tracking page