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}}".
Related
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.
We are using Xalan XSLT 1.0 in Java and we want to pass a variable to a template match to avoid hard-coding element names in the XSL file. The style sheet compiles, but the date returned is wrong. Are we using the correct syntax?
Possible XML inputs...
<books>
<book/>
<book/>
</books>
<dvds>
<dvd/>
<dvd/>
</dvds>
<xsl:variable name="matchElement" select="'book'"/>
<!-- OR -->
<xsl:variable name="matchElement" select="'dvd'"/>
<xsl:template match="/*[local-name() = $matchElement]">
This xsl:template:
<xsl:template match="/*[local-name() = $matchElement]">
is matching from root.
Either remove the / from /* or change it to //* (depending on how the rest of your stylesheet is designed).
Also, if you use xsl:param instead of xsl:variable, you can set the value from the command line.
Your variable syntax is correct, but note that it is technically illegal to use variable or parameter references in XSLT 1.0 match patterns. It is possible, however, that Xalan has implemented this behavior outside of the standard. (#DevNull's comment about your expression also applies.)
The relevant parts of the code:
<xsl:variable name="apos">'</xsl:variable>
<xsl:variable name="and" select='"'"' />
<xsl:value-of select="translate(products_name/node(),$and,$apos)"/>
I'm thinking this should be a simple thing and that the above code should work but it doesn't effect the output at all.
(I used variables because names cannot begin within an ampersand and using just an apostrophe brings up a compile error.)
I've tested the code to make sure the translate is working using strings and there are no errors there.
Any help would be greatly appreciated.
You are on the right track, but not yet there: Your problem is, that XSL is a language that itself is written using XML. For all XML languages, the parser automatically decodes XML entities. The XSLT engine only comes afterwards.
As a result, the XSLT engine neither does nor can distinguish whether you wrote ' or ' - it's the same. For your problem, this has two effects:
You have to use a variable containing the apostrope - this is because the apostrophe itself is reserved for string literals in expressions that may contain functions. Even for <xsl:value-of select="translate(products_name/node(),$and,''')"/>, the XML parser transforms the entity into an apostrophe, i.e. <xsl:value-of select="translate(products_name/node(),$and,''')"/>
You have to escape the ampersand used in the string you search for: for the XSL engine, the variable "and" contains the value ', i.e. you are replacing an apostrophe with an apostrophe.
Working solution:
<xsl:variable name="apos">'</xsl:variable>
<xsl:value-of select='translate(text(), "'", $apos)'/>
Technically, there's no difference in any XML between ', ' and ', they're different ways of representing exactly the same thing. Therefore, that translate call shouldn't do anything.
It depends on how you're transforming it, where that output is (attribute value or element?), and how the output is serialized to text, but your problem isn't with your XSLT.
I have a problem with text with apostrophe symbol
example i try to test this xml having the symbol is then how can i compare ?
<xsl:for each select="country[nation='India's]">
this is statement showing error
Regards
Nanda.A
One way to do it would be:
<xsl:variable name="apos" select='"'"'/>
<!-- ... later ... -->
<xsl:for-each select="country[nation=concat('India', $apos, 's')]">
The problem here is twofold:
XSLT defines no way of character escaping in strings. So 'India\'s' is not an option.
You must get through two distinct layers of evaluation.
These are:
XML well-formedness: The XML document your XSLT program consists of must be well-formed. You cannot violate XML rules.
XSLT expression parsing: The resulting attribute value string (after XML DOM parsing is done) must be make sense to the XSLT engine.
Constructs like:
<xsl:for-each select="country[nation='India's']">
<xsl:for-each select="country[nation='India's']">
pass the XML layer but violate the XSLT layer, because in both cases the effective attribute value (as stored in the DOM) is country[nation='India's'], which clearly is an XPath syntax error.
Constructs like:
<xsl:for-each select="country[nation=concat('India', "'", 's')]">
<xsl:for-each select="country[nation=concat("India", "'", "s")]">
clearly violate the XML layer. But they would not violate the XSLT layer (!), since their actual value (if the XSLT document could be parsed in the first place) would come out as country[nation=concat('India', "'", 's')], which is perfectly legal as an XPath expression.
So you must find a way to pass through both layer 1 and layer 2. One way is the variable way as shown above. Another way is:
<xsl:for-each select="country[nation=concat('India', "'", 's')]">
which would appear to XSLT as country[nation=concat('India', "'", 's')].
Personally, I find the "variable way" easier to work with.
I'll spare you the details because they would be needlessly confusing. Long story short, I'm using XSLT 1.0 to generate XSL documents, I'm trying to compare a variable to a literal string, and that string may contain quotes and apostrophes.
For the sake of simplicity, let's say that this literal is composed of two characters: a quote followed by an apostrophe. In reality, it can be any text really. Is there a simpler way to do this:
<xsl:if test="$var = concat('"', "'")">
than this?
<xsl:variable name="str">"'</xsl:variable>
<xsl:if test="$var = $str">
I have checked XPath's specs and there doesn't seem to be a way to escape characters, so the following would not work as desired:
<xsl:if test="$var = '"''">
Thanks!
There's no way to do it neatly in XPath 1.0. In XPath 2.0, you can escape both kinds of quotes by doubling.
& quot;& amp;&(!)apos; -looks much better, but what did you want to get?
In anyway: once I have written application that deals with producing of Javascript over XSLT.
The same problem with huge number of & quot;,... we solved in 2 ways:
Declare global xsl:param, $q - looks shorter than & quot;
Use 'translate' XPath function, make assumption '!' - is a & quot;, # is a & amp; ..