0

Need to convert the XML to String

Input XML:

<Texts>
<text>123</text>
<text>456</text>
<text>789</text>
</Texts>

Output String

T1=123&T2=456&T3=789

I'm using following XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
        <xsl:for-each select="Texts">
            <xsl:apply-templates mode="concat" select="text" />
        </xsl:for-each>
</xsl:template>

<xsl:template match="text" mode="concat">
    <xsl:variable name="position" select="position()"/>
    <xsl:if test="position() = 1">
        <xsl:text>P($position)=</xsl:text>
    </xsl:if>
    <xsl:value-of select="." />
    <xsl:if test="position() = last()">
        <xsl:text></xsl:text>
    </xsl:if>
    <xsl:if test="position() = last()"> 
    <xsl:text>&amp;P$position=</xsl:text>
    </xsl:if>
</xsl:template> 

</xsl:stylesheet>

Let me know whats wrong. The elements text in XML can be any number

2
  • 1
    It's much easier if you let us know what's wrong! :P What output are you getting? Commented Oct 16, 2013 at 16:14
  • This is the output i got P($position)=123456789&P$position= Commented Oct 16, 2013 at 16:26

4 Answers 4

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

  <xsl:template match="/">
    <xsl:apply-templates select="Texts/text" />
  </xsl:template>

  <xsl:template match="text">
    <xsl:value-of select="concat('P', position(), '=', .)" />
    <xsl:if test="position() &lt; last()">&amp;</xsl:if>
  </xsl:template> 

</xsl:stylesheet>

outputs

P1=123&P2=456&P3=789

Note that you actually should use URL encoding on the values of each <text>, but that's not built into XSLT 1.0 (but 2.0 has a function for it).

If you are dealing with number values you should be fine, if not you should look for ways to get a URL encoding function into your stylesheet. There are several ways to extend XSLT with external functions, it depends on your XSLT engine which one applies to you.

Sign up to request clarification or add additional context in comments.

1 Comment

For what it's worth, EXSLT has the function str:encode-uri which some XSLT 1.0 processors support.
1

Sometimes it's easier to use xsl:for-each:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="/">
        <xsl:for-each select="Texts/text">
            <xsl:if test="position() != 1">&amp;</xsl:if>T<xsl:value-of select="position()" />=<xsl:value-of select="." />
        </xsl:for-each> 
    </xsl:template>
</xsl:stylesheet>

2 Comments

That could be greatly simplified by using concat(). Well. It could be simplified a little. :)
My XSLT-jitsu is rusty =)
1

The simplest/fastest way to do it is (if you have in XPath 2):

 string-join(//text / concat("T", position(), "=", .), "&")

Or better, if you actually need it url encoded, and put it verbatim in a XSLT:

 string-join(//text / concat("T", position(), "=", encode-for-uri(.)), "&amp;")

Comments

0

It can be done in XPath 2.0 (and therefore XSLT 2.0) like this:

string-join(
  for $i in 1 to count(//text) 
    return concat('T', $i, '=', (//text)[$i]), 
  '&')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.