We help IT Professionals succeed at work.

xslt 1.0 - How to split value

Darius
Darius asked
on
2,286 Views
Last Modified: 2017-03-12
Hi Guys,

Please assist how to split input value into different many values and  store in variables
input always has four values divided by pipe line.

input: 
<LINE>value_1|value_2|value_3|value_4</LINE>

Open in new window


How to store these values in separate variables?


<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" version="1.0"/>

  <xsl:template match="/">

    <xsl:variable name="test1" select="" />
    <xsl:variable name="test2" select="" />
    <xsl:variable name="test3" select="" />
    <xsl:variable name="test4" select="" />

    <Lines>
      <xsl:value-of select="LINE" />
    </Lines>

  </xsl:template>
</xsl:stylesheet>

Open in new window



Ecpected output:
<Lines>value_1</Lines>
<Lines>value_2</Lines>
<Lines>value_3</Lines>
<Lines>value_4</Lines>

Open in new window


Thank you!
Comment
Watch Question

Author

Commented:
Sorted how to split files...

but in my situation every value has to be stored in variables!


  <xsl:template match="/">
    <xsl:for-each select="LINE">
      <xsl:call-template name="strSplit">
        <xsl:with-param name="str" select="."/>
      </xsl:call-template>
    </xsl:for-each>
  </xsl:template>


  <xsl:template name="strSplit">
    <xsl:param name="str"/>

    <xsl:variable name="afterPipe"
        select="substring-after($str, substring-before($str,substring-before(normalize-space($str), '|')))"/>

    <xsl:choose>
      <xsl:when test="contains($afterPipe, '|')">
        <lines>
          <xsl:value-of select="substring-before($afterPipe, '|')"/>
        </lines>
        <xsl:call-template name="strSplit">
          <xsl:with-param name="str" select="substring-after($afterPipe, '|')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <lines>
          <xsl:value-of select="$afterPipe"/>
        </lines>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Open in new window

Gertone (Geert Bormans)Information Architect
CERTIFIED EXPERT
Top Expert 2006

Commented:
First I would like to point out that XSLT2.0 has been a recommendation for about 10 years now.
Requirements like this are largely helped by using XSLT2.0
(and it is getting easier by the day to replace your XSLT1.0 processor with an XSLT2.0 processor:
saxon for Java, .net, C-bindings, JS... and http://exselt.net/ for .NET)
I am saying this because the "I have to use XSLT1.0 argument very often means "I have not seriously looked for XSLT 2.0 options"

Anyway, that was a side note

In XSLT1.0 you need to use recursive processing as you do.
There is however no such thing as dynamic variables
With this I mean, there simply is no way in XSLT to create an amount of variables depending on the number of piped values
So, if you need a variable created per value in a piped string with no indication how many values there can be, your only option is to create an XSLT from your XML using XSLT and then use that generated XSLT for transformation....
XSLT2.0 would be a hell of a lot easier

If there are always four values, you could pass an extra parameter telling exactly which value you need.
Will post an example later today
Gertone (Geert Bormans)Information Architect
CERTIFIED EXPERT
Top Expert 2006

Commented:
Before I do that, I would also like to point out that the requirement "I need that in a variable" usually is poor XSLT design. XSLT has no variables in a strict sense. XSLT has locally scoped constants named xsl:variable. Developing XSLT with a procedural mindset tends to lead to an abundance of variables. Try to think more functional... you will find out you would not need all those variables at all
Information Architect
CERTIFIED EXPERT
Top Expert 2006
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
Gertone (Geert Bormans)Information Architect
CERTIFIED EXPERT
Top Expert 2006

Commented:
so, I first showed how to not use xsl:for-each for the LINE elements. Functional thinking suggests not using xsl:for-each when it can be avoided (it is a common understood best practice)

Then I made the recursive template very explicit so you can add your own logic for the boundary conditions if you want
(I would additionaly test for an 'NaN' index to be sure, but that is when used in production)

Please note that variables are scoped.
If you need the variables used in different templates you need to pass them as parameter

Author

Commented:
Hi Geert,

Thank you very much for your detailed explanation and examples. Regarding to this solution this is not my choice and decision and I don't have option to use processor 2.0. In my situation and my understand I am using XSLT processor from Microsoft. And they don't have (support) a 2.0 processor.

Thank you very much!
Gertone (Geert Bormans)Information Architect
CERTIFIED EXPERT
Top Expert 2006

Commented:
It is correct that microsoft does not have a 2.0 processor, and they made it clear very early in the process that they will never have one.
BUT
if you are doing XSLT from within a .net program (C#, F#, VB....) you can easily set up the transformer from Saxon.NET or Exselt
The .net components also work from the commandline on windows
So using .net technologies is not an argument for sticking to XSLT1

Maybe you can tell more about what exactly you are doing, maybe we can achieve a way to use XSLT2

Maybe I can convince you that
       <xsl:variable name="all-values" select="tokenize-string(., '|')">

and
        <lines><xsl:value-of select="$all-values[1]"/></lines>
        <lines><xsl:value-of select="$all-values[2]"/></lines>
        <lines><xsl:value-of select="$all-values[3]"/></lines>
        <lines><xsl:value-of select="$all-values[4]"/></lines>

is a very attempting alternative to your code above

Author

Commented:
I have mapping solution on XML files. I'm new in company and I don't have much experience. Back end of transformation service it was created long time ago and after discussion with other developers there is no plan to change anything. I had already few solution when version 2.0 will be save my time. But in reality we still using version 1.0  :(

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.