Project

Profile

Help

Bug #5673

closed

ixsl:set-property and URLs in property names

Added by Martynas Jusevicius 3 months ago. Updated about 2 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Category:
IXSL extensions
Sprint/Milestone:
Start date:
2022-08-31
Due date:
% Done:

100%

Estimated time:
Applies to JS Branch:
2, Trunk
Fix Committed on JS Branch:
2, Trunk
Fixed in JS Release:
SEF Generated with:
Platforms:
Company:
Martynas Jusevičius
Contact person:
Martynas Jusevičius
Additional contact persons:
-

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 :)

Actions #1

Updated by Martynas Jusevicius 3 months ago

Worked around like this:

<xsl:variable name="js-statement" as="element()">
    <root statement="{{ &quot;Q{{&ldt;}}base&quot;: &quot;{$ldt:base}&quot; }}"/>
</xsl:variable>
<xsl:variable name="stylesheet-params" select="ixsl:eval(string($js-statement/@statement))"/>

Actions #2

Updated by Norm Tovey-Walsh 3 months ago

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?

Actions #3

Updated by Martynas Jusevicius 3 months ago

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.

Actions #4

Updated by Norm Tovey-Walsh 3 months ago

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.

Actions #5

Updated by Michael Kay 3 months ago

Perhaps

name="`a.b.c`"

allowing a backtick within the property name to be escaped as a double-back-tick?

Actions #6

Updated by Norm Tovey-Walsh 3 months ago

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.

Actions #7

Updated by Norm Tovey-Walsh 3 months ago

  • 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.

Actions #8

Updated by Martynas Jusevicius 3 months ago

  • 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 <
> wrote:

Actions #9

Updated by Norm Tovey-Walsh 3 months ago

Saxonica Developer Community 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

Actions #10

Updated by Martynas Jusevicius 3 months ago

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 <
> wrote:

Actions #11

Updated by Norm Tovey-Walsh 3 months ago

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.

Actions #12

Updated by Martynas Jusevicius 3 months ago

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="..."/>
Actions #13

Updated by Norm Tovey-Walsh 3 months ago

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>
Actions #14

Updated by Debbie Lockett about 2 months ago

  • Sprint/Milestone set to SaxonJS 2.5
Actions #15

Updated by Norm Tovey-Walsh about 2 months ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in JS Release set to SaxonJS 2.5

Fixed in SaxonJS 2.5.

Actions #16

Updated by Norm Tovey-Walsh about 2 months ago

See also #5714 for documentation fixes to be applied.

Please register to edit this issue

Also available in: Atom PDF Tracking page