I have an XSLT implementation that hyphenates strings following latex patterns, i.e. inserts soft hyphens in strings. I call this function like this:
<xsl:template match="p[lang('en')]/text()">
<xsl:analyze-string select="." regex="w+">
<xsl:matching-substring>
<xsl:value-of select="fn:hyphenate(., '', 'en')"/>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
Now, before I call the hyphenate
function, I would like to consult a list of exceptions. I’m fairly flexible about the format in which I get the exceptions, but I would also like to use this opportunity to learn how to take advantage of json objects from within XSLT 3.0.
So let’s say i have a JSON file called exceptions.json
that looks like this:
{
"en" :{
"recognizance": "re-cog-ni-zance",
"reformation": "ref-or-ma-tion",
"retribution": "ret-ri-bu-tion",
"table": "ta-ble"
},
"de" : {
//etc.
}
}
(I am not using soft hyphens in the above example because they wouldn’t show on Stackoverflow, but that’s irrelevant for the question I am asking).
How could I read (and parse?) the contents of the JSON file into a variable called $exceptions
, so that I could most efficiently do something like:
<xsl:template match="p[lang('en')]/text()">
<xsl:analyze-string select="." regex="w+">
<xsl:matching-substring>
<xsl:choose>
<xsl:when test="">
<!--test if matched string is a key in my json object and return the
corresponding value. for instance, if the matched substring here is
"table", I'd like to return something like
<xsl:value-of select="$exceptions['en']['table']"/> ,
i.e. "ta-ble", using whatever notation may be correct for this
kind of thing. -->
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="fn:hyphenate(., '', 'en')"/>
</xsl:otherwise>
</xsl:choose>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
Many thanks in advance!
2
Answers
Well, the XPath 3.1 and the XSLT 3.0 specs are online, so you could have found the necessary functions (https://www.w3.org/TR/xpath-functions-31/#func-json-doc, https://www.w3.org/TR/xpath-functions-31/#func-map-contains) and notations (https://www.w3.org/TR/xpath-31/#id-lookup).
Use e.g.
<xsl:variable name="exceptions" select="json-doc('exceptions.json')"/>
, the you can access e.g.map:contains($exceptions?en, .)
to check whether the current word is in theen
map.Example: (reading JSON inline for self-containedness):
Online fiddle.
Another option is to convert the JSON to XML, then process it as such.
In your example, this could probably look something like:
XSLT 3.0
Untested, because you did not provide a reproducible example. Do note that I am using the
fn
prefix as intended by the W3C Recommendation; you will need to use another prefix for your own function.