mevorahde
mevorahde

Reputation: 95

XSLT 1.0: Substring multiple values

I have the following element and value:

XML:

<Location>Wing: ; Room: A; Bed: NAH; Group: 195;</Location>

I'm trying to sub string each value to it's own element.

My Current XSLT:

<PL.1>
      <xsl:value-of select="substring-before(//Location, ' ; Room:')" />
</PL.1>
<PL.2>
      <xsl:value-of select="substring-before(//Location, 'Bed:')" />
</PL.2>
<PL.3>
      <xsl:value-of select="substring-before(//Location, 'Group:')" />
</PL.3>
<PL.4>
      <xsl:value-of select="substring-after(//Location, 'Group:')" />
</PL.4>

The expected result that I'm going for is the following:

<PL.1>Wing: ;</PL.1>
<PL.2>Room: A;</PL.2>
<PL.3>Bed: NAH;</PL.3>
<PL.4>Group: 195;</PL.4>

I know my sub string is wrong, but I'm not sure of the correct way to pin point certain points. Examples that I've seen aren't calling a variable and usually only separates two things, so I'm having a hard time with the concept of breaking out more than two items.

Current Results by XSLT:

<PL.1>Wing:</PL.1>
<PL.2 />
<PL.3> 195;</PL.3>
<PL.4 />

Upvotes: 1

Views: 1217

Answers (3)

imran
imran

Reputation: 461

<xsl:template match="Location">
        <xsl:variable name="a" select="substring-before(.,' Room')"/>
        <xsl:variable name="b" select="substring-before(substring-after(.,'Wing: ; '), ' Bed')"/>
        <xsl:variable name="c" select="substring-before(substring-after(.,' Room: A; '),' Group')"/>
        <xsl:variable name="d" select="substring-after(.,'NAH; ')"/>
        <PL.1>
            <xsl:value-of select="$a"/>
        </PL.1>
        <PL.2>
            <xsl:value-of select="$b"/>
        </PL.2>
        <PL.3>
            <xsl:value-of select="$c"/>
        </PL.3>
        <PL.4>
            <xsl:value-of select="$d"/>
        </PL.4>
    </xsl:template>
Use this code

Upvotes: 0

zx485
zx485

Reputation: 29022

Use a recursive template like in this XSLT-1.0 solution:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/root">                        <!-- Adapt to your real conditions -->
    <xsl:call-template name="NextStr">
      <xsl:with-param name="str" select="Location" /> <!-- Change to //Location if appropriate -->
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="NextStr"> 
    <xsl:param name="str" />
    <xsl:param name="cnt" select="1" />
    <xsl:if test="normalize-space($str)">
      <xsl:element name="{concat('PL.',$cnt)}">
        <xsl:value-of select="normalize-space(concat(substring-before($str,';'),';'))" />
      </xsl:element>
      <xsl:call-template name="NextStr">
        <xsl:with-param name="str" select="substring-after($str,';')" />
        <xsl:with-param name="cnt" select="$cnt + 1" />
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

This stylesheet derives the PL.x element names from a counter passed to the named template NextStr. You could remove the trailing ; by removing the respective concat(...) from the expression.

Output is:

<PL.1>Wing: ;</PL.1>
<PL.2>Room: A;</PL.2>
<PL.3>Bed: NAH;</PL.3>
<PL.4>Group: 195;</PL.4>

Upvotes: 1

user6117820
user6117820

Reputation:

Try using

<PL.1>
      <xsl:value-of select="substring-before(//Location, ' ; Room:')" />
</PL.1>
<PL.2>
      <xsl:value-of select="substring-before(//Location, ';Bed:')" />
</PL.2>
<PL.3>
      <xsl:value-of select="substring-before(//Location, ';Group:')" />
</PL.3>
<PL.4>
      <xsl:value-of select="substring-after(//Location, ';Group:')" />
</PL.4>

Upvotes: 0

Related Questions