I have an XML element with long content, lets say
<LongString>Here we have a lengthy string which contains lots of words separated by spaces and it needs to be split</LongString>
I want to split it into two elements (lets call them StartString and EndString) according to following rules:
StartString will contain as many characters as possible, but at most 40 characters (If LongString has less than 40 characters, then StartString will be equal to LongString and EndString will be empty)
If there are spaces withing the first 40 characters of LongString, it will be split at a space
(If there are no spaces within the first 40 characters, then the split will be after 40 characters anyway)
StartString will not end with a space and EndString will not start with a space
So the example above should be transformed into:
<StartString>Here we have a lengthy string which</StartString>
<EndString>contains lots of words separated by spaces and it needs to be split</EndString>
Whereas
<LongString>Just a short string</LongString>
will become
<StartString>Just a short string</StartString>
<EndString></EndString>
and
<LongString>12345678901234567890123456789012345678901234567890 spaces only at the end</LongString>
will become
<StartString>1234567890123456789012345678901234567890</StartString>
<EndString>1234567890 spaces only at the end</EndString>
How to accomplish this with XSLT?
In XSLT 2 or later, if you want to process/analyze text and create nodes, xsl:analyze-string can help:
<xsl:template match="LongString">
<xsl:analyze-string select="." regex="^(.{{1,39}}$|[^ ]{{40}}|.{{1,39}} )">
<xsl:matching-substring>
<StartString>
<xsl:value-of select="if (ends-with(., ' ')) then substring(., 1, string-length(.) - 1) else ."/>
</StartString>
</xsl:matching-substring>
<xsl:non-matching-substring>
<EndString>
<xsl:value-of select="."/>
</EndString>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
Related
I have a input string like this,without any space
51=2MA011362X17=MG127AJ4015AG1A20=022=M35=U48=9CVRVC449
Here, number before = is key and after is value. From this string I have to fetch value of 17= (basically fetch the value MG127AJ4015AG1A)
I used <xsl:value-of select="substring-before(substring-after(.,'17='), '=')"/> which is giving me result: MG127AJ4015AG1A20, now I am stuck with removing these last 2 numeric values (20). totally confused how this an be achieved.
Final output string should be - MG127AJ4015AG1A
If it is the case that the number at the end will always be two digits, you put your current expression in a variable, and use substring to remove the last two characters, like so:
<xsl:variable name="match" select="substring-before(substring-after(.,'17='), '=')" />
<xsl:value-of select="substring($match, 1, string-length($match) - 2)"/>
I have my string as below
<Text>Pack:NA Lead:20 Dimension:235</Text>
And need to map
NA to outputfield1
20 to outputfield2
235 to outputfield3
How to do this correctly in xslt mapping where the values 'NA,20,235' could be different each time?
I could only see substring component which takes length as second parameter.
That leads requires several steps to achieve this.
Any better solution to just take the value between Lead: and Dimension for outputfield2?
To extract the Pack value, you can use:
<xsl:value-of select="substring-before(substring-after(Text, 'Pack:'), ' ')" />
To extract the Lead value, use:
<xsl:value-of select="substring-before(substring-after(Text, 'Lead:'), ' ')" />
To extract the Dimension:
<xsl:value-of select="substring-after(Text, 'Dimension:')" />
<xsl:variable name="groups" as="element(group)*">
<xsl:analyze-string regex="^^([0-9-]+)([A-Z ]*)[ ]*([\(](.*)[\)])*$" select="/fault/informations/restriction1">
<xsl:matching-substring>
<group>
<x><xsl:value-of select="regex-group(1)"/></x>
<y><xsl:value-of select="regex-group(4)"/></y>
</group>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:variable>
it was allready in
XSL Analyze-String -> Matching-Substring into multiple variables
but my question is how to use it on example to concate
eg regex-group(1) with other element outside regex path "/fault/informations/restriction2"
so simple IMPUT XML:
<fault >
<information>
<reference1>22-00 X (AA - 03 StoLAT)</reference1>
<opr>Sample sam (66-33) Sample</opr>
</information>
</fault>
and OUTPUT I would like to have
in one element
<mytrouble>
<trouble12>AA - 03 StoLAT , Sample sam Sample</trouble12>
</mytrouble>
so the rgex group 4 - text inside ( ) from <reference1> and the whole text from opr
ps
currently by transforming:
Cannot match item type with required type Error location:
xsl:stylesheet / xsl:template / xsl:element / xsl:variable /
#as
Details XTTE0570 : The required item type of variable ' groups ' is
' element(Q{http://xml.event/1.0}group) ' ,
the supplied item type is ' text() '
GREAT THANX for
michael.hor257k
almost there - just the result indicates header
<trouble12 xmlns:fn="http://www.w3.org/2005/xpath-functions">AA - 03 StoLATSample sam Sample</trouble12>
my question is how to use it on example to concate eg regex-group(1)
with other element outside regex path
"/fault/informations/restriction2"
To refer to another node within the xsl:analyze-string instruction, capture it in a variable first - for example:
<xsl:variable name="opr" select="fault/information/opr" />
<xsl:analyze-string regex="^^([0-9-]+)([A-Z ]*)[ ]*([\(](.*)[\)])*$" select="fault/information/reference1">
<xsl:matching-substring>
<trouble12>
<xsl:value-of select="regex-group(4)"/>
<xsl:value-of select="$opr"/>
</trouble12>
</xsl:matching-substring>
</xsl:analyze-string>
I have a number such as: 457342137 but i want to display it as a 457 342 137.
I have something like this:
<xsl:template match="klient/#numer_telefonu">
<xsl:variable name="numer" select="." />
<xsl:value-of select="format-number($numer, '### ### ###')" />
</xsl:template>
but it does not work.
If you want to use a non-standard 'grouping' separator, you first need define the symbols you are going to use in your format command as follows:
<xsl:decimal-format name="spaces" grouping-separator=" " />
Then, you can reference this format in the command itself as follows:
<xsl:value-of select="format-number($numer, '# ###', 'spaces')" />
Further information about decimal-format can be found at http://www.w3.org/TR/xslt#format-number
A telephone number is a string, not a number and you shouldn't try formatting it as one. Technically, you could do:
<xsl:value-of select="translate(format-number(., '#,###'), ',', ' ' )" />
to achieve the desired result in your example. However, given a "number" such as "057342137" the result will be "57 342 137" (leading zeros stripped). You should be using string functions to manipulate a string.
How to use the choose condition in XSLT when the below requirement is needed
<xsl:choose>
<xsl:when test="contains(#name,'top %d holdings' ) ">
<!--code-->
</xsl:when>
</xsl:choose>
It should select all the data containing....
top 5 holdings
top 10 holdings
top 30 holdings
top 27 holdings
top * holdings
If you were using XSLT2.0 here, you could use the matches function which allows you to match text by means of a regular expression
<xsl:when test="matches(#name, '.*top \d+ holdings.*')">
On the other hand, if you were using XSLT 1.0, then the matches function is not available. One way you could do it in your very specific case is extract the text before "holdings" that occurs before "top" and check it is a number:
<xsl:when test="string(number(substring-before(substring-after(#name, 'top '), ' holdings' ) )) != 'NaN'">
You can use substring-before() and substring-after() to get the text between top and holdings, and then use the translate() function to remove numbers and the * character, and then verify that the result is an empty string.
<xsl:choose>
<xsl:when
test="translate(
substring-before(substring-after(#name, 'top '), ' holdings' ),
'0123456789*',
'') = '' ">
<!--code-->
</xsl:when>
</xsl:choose>