Xpath: pass an 'include everything' parameter to [starts-with(...)] - regex

Using Saxon HE/Xpath 2
To filter my xml file of a list of businesses by 'BusinessType' I pass a parameter (ie "Restaurant" or "School") to the xsl file:
"java.exe" -jar "saxon9he.jar" -s:FHRS.xml -xsl:FHRS.xsl BusinessType="Restaurant"
The BusinessType category names are quite long so to save typing I pass the parameter to starts-with:
<xsl:param name="BusinessType"/>
<xsl:variable name="ID_New" select="//Details[starts-with(BusinessType,$BusinessType)]/FHRSID"/>
This is just a one line example. The same format is used multiple times in the xsl routine.
Is it possible to pass an 'return everything' wildcard parameter to $BusinessType? I've tried * and .*. I'm not well versed in RegEx.

The starts-with function https://www.w3.org/TR/xquery-operators/#func-starts-with works only with strings, not with regular expressions. However an empty sequence or an empty string as the second argument means the function returns true so you could simply define <xsl:param name="BusinessType" select="()"/> and then, if you don't want to filter, you don't set the parameter and the predicate starts-with(BusinessType,$BusinessType) is always true.
If you want to use regular expressions you need to use the matches function e.g. matches(BusinessType,$BusinessType) where a pattern to match any starting character would be if you set the param to ^.*.

Related

XSLT 2 analyze-string finding block names

I am trying to detect strings in other languages in my XML.
I thought I could use something like :
<xsl:analyze-string select="$mystring" regex="(\p{InGreek})" >
but I am unable to make this work.
Do you think this is possible in XSLT ? How would you do this ?
Thanks a lot.
Maria
(XSLT 2, Saxon-HE 9.8.0.8)
I think the right category name would be IsGreek so the regular expression would be \p{IsGreek}, however as the regex attribute of xsl:analyze-string allows attribute value templates you either need to put the expression into a string variable <xsl:param name="pattern" as="xs:string">\p{IsGreek}</xsl:param>you reference as regex="{$pattern}" or you need to duplicate the curly braces, as in regex="\p{{IsGreek}}".

regEx is not working while parsing through xsl

hi i want to put a regex for my xml tag the tag is start with <SV1> here i want to put regEx for 1 . it can be any number from 0 to 1 . it is not working
i have tryed with below code.
<LineAmount><xsl:value-of select="SV*.[0-9].*/SV102"/></LineAmount>
it is not woking can some body help me.
If you want to use regular expression matching in XSLT then you need to use at least XSLT 2.0 (like for instance with an XSLT 2.0 processor like Saxon 9 or XmlPrime) and for element names (or node names in general) you need to use a predicate that tests the name e.g.
<xsl:value-of select="*[matches(local-name(), 'SV[0-9]')]/SV102"/>
selects SV102 with a parent of the name SV0, SV1, SV2, SV3 and so on.

XSLT/XPath quoting: XPath within an XPath-Function within XSLT

Here we're using double quotes at the XSLT level; single quotes at the XPath function level, but when we need to embed an XPath expression within the XPath function, how do we quote that?
<xsl:value-of select="document('price-list.xml','/im_prices/row/UPC_Code[text()='abc']"/>
^^^^^
(scroll to the right)
Not sure about that, I have always used the node-set form of:
<xsl:value-of select="document('price-list.xml')/im_prices/row/UPC_Code[text()='abc']"/>
but that may be vendor specific (however, have never known it not to work!)
The second argument of document() is a node-set, not a string, so the problem should not arise. However, there are of course other cases where it can arise.
In XSLT 2.0:
if you want to include the attribute delimiter in a string, escape it as " or &apos;
if you want to include the string delimiter in a string, double it as '' or "".
In XSLT 1.0, the second option is not available. You can get around it either
(a) by swapping the character used for the attribute delimiter and the string delimiter
(b) by using concat() to build the string

XSLT substring and hash tag

Can someone tell me why this is not working?
Throughout my document I have several column breaks marked as follows: <cb ed="#S" n="45rb"/>
The hash tag is there to refer to another element where the source document is identified.
Now I want to display the column break in the following document. So that it looks like this:
|S45rb|. I thought I could use a simple substring function to get rid of the hash tag like so.
<xsl:template match="TU:cb">
<xsl:variable name="hashms"><xsl:value-of select="//TU:cb/#ed"/></xsl:variable>
<xsl:variable name="ms"><xsl:value-of select="substring($hashms,1,1)"/></xsl:variable>
<span>| <xsl:value-of select="$ms"/> <xsl:value-of select="//TU:cb/#n"/> |</span>
</xsl:template>
When I do it this way I get the following result: |#75ra|. Shouldn't the first 1 in the argument refer to the first character of the string and then the second 1 tell it to move over one character and leave me with the desired S? Instead I don't get the S but only the hash tag. Is there something about hash tags and strings I do not know?
Thanks for your help.
XSL is not 0 base, if you want to start at the second character (after the #), it should be 2 rather than 1.
http://www.w3schools.com/Xpath/xpath_functions.asp
substring($hashms,2,1) = S
You can also omit the length, which might be of benefit for extensibility later on. Especially if whatever comes after the # is the identifier, why limit your code?
substring($hashms,2) = S
substring('#S2',2) = S2

XSLT/XPath : No upper-case function in MSXML 4.0?

I try to use upper-case() in an XPATH, my parser is MSXML 4.0, and I get :
upper-case is not a valid XSLT or XPath function.
Is it really not implemented ?
There are no functions in xslt 1.0 to convert to uppercase or lowercase. Instead do the following:
If it is required in a lot of places:
Declare these two xsl variables (this is to make the xslt more readable)
<!-- xsl variables up and lo and translate() are used to change case -->
<xsl:variable name="up" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lo" select="'abcdefghijklmnopqrstuvwxyz'"/>
And use them in your translate function to change the case
<xsl:value-of select="translate(#name,$lo,$up)"/>
If you need to use it in just one place, no need to declare variables
<xsl:value-of select="translate(#name,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
Maybe this can help you:
translate(string, string, string)
The translate function takes a string and, character-by-character, translates characters which match the second string into the corresponding characters in the third string. This is the only way to convert from lower to upper case in XPath. That would look like this (with extra white space added for readability). This code would translate the employee last names to upper case and then select those employees whose last names begin with A.
descendant::employee[
starts-with(
translate(#last-name,
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
"A"
)
]
If the second string has more characters than the third string, these extra characters will be removed from the first string. If the third string has more characters than the second string, the extra characters are ignored.
(from http://tutorials.beginners.co.uk/professional-visual-basic-6-xml-part-1-using-xml-queries-and-transformations.htm?p=3)