0

I am trying to handle a space issue with the Phone number and faxNumber elements in my XML.

The elements are:

<PhoneNumber>0870 6071352</PhoneNumber>
<FaxNumber>01722 422301</FaxNumber>

but they can also be:

0870 6071352

so I need to remove the leading and trailing spaces, keep the space between any numbers, and output the result formatted to a fixed length of 71 characters using leading spaces.

so I am trying to write a named template that will remove the spaces then pad the output with leading spaces to a fixed length of 71 characters.

here is my defined template but it doesn't compile - I get an error Expression expected <- and I can't find out what is missing or wrong

<!-- format the phone number with no spaces and output to 71 characters with leading spaces -->
<xsl:template name="FormattedPhoneFaxNumber">
    <xsl:param name="text"/>
    <xsl:choose>
      <xsl:when test="contains($text,' ')">
        <xsl:value-of select="substring-before($text,' ')"/>
        <xsl:value-of select=""/>
        <xsl:call-template name="FormattedPhoneFaxNumber">
          <xsl:with-param name="text" select="substring-after($text,' ')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="substring(concat('                                                                       ', $text), 1, 71)"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

can anyone show me where I am going wrong?

The reason I need to do this is because I have to handle the element being empty, having leading or trailing spaces as well as the value, or just the value, and we need to output two fiwlds with leading spaces to a max length of 71 characters.

Our Man in Bananas
  • 5,809
  • 21
  • 91
  • 148

1 Answers1

2

Remove the line:

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

The select attribute should be an XPath expression, and an empty string is not a valid expression.

But you don't actually need the recursive template at all, if you want to remove spaces from a string you can do it using translate(theString, ' ', ''), and you may want to add a normalize-space to handle other whitespace characters like tabs. For example, the following stylesheet

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

  <xsl:template name="FormattedPhoneFaxNumber">
      <xsl:param name="text"/>
      <xsl:variable name="noSpaces" select="translate(normalize-space($text), ' ', '')" />
      <!-- using fewer spaces for this example, but in your real case use 71 -->
      <xsl:value-of select="substring(concat('                            ',
          $noSpaces), string-length($noSpaces) + 1)"/>
  </xsl:template>

  <xsl:template match="/">
    <xsl:for-each select="*/*">
      <xsl:text>>>></xsl:text>
      <xsl:call-template name="FormattedPhoneFaxNumber">
        <xsl:with-param name="text" select="." />
      </xsl:call-template>
      <xsl:text>&lt;&lt;&lt;&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

when run on the following XML document

<root>
  <num>   </num>
  <num>0123  456 7890   </num>
  <num>&#9;212-345 6789</num><!-- &#9; is a tab character -->
  <num/>
</root>

produces the correct result

>>>                            <<<
>>>                 01234567890<<<
>>>                 212-3456789<<<
>>>                            <<<

In particular empty elements produce completely blank strings of the correct length.

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
  • thanks but when I use `translate`, when the element is empty I get an incomplete string – Our Man in Bananas Sep 04 '14 at 16:15
  • how could I keep the space in `020 123456` but lose any trailing and leading spaces, plus output the right length of 71 characters even when it's empty? – Our Man in Bananas Sep 04 '14 at 16:22
  • @Philip I can't reproduce your problem - when I test my template with an empty string value for `$text` I get the correct output of 71 blank spaces. – Ian Roberts Sep 04 '14 at 16:23
  • 1
    @Philip If you want to lose leading and trailing spaces but preserve internal spaces then you can use _just_ the `normalize-space` without the `translate`. The `normalize-space` function strips leading and trailing whitespace and converts any internal runs of one or more whitespace characters to a single space. – Ian Roberts Sep 04 '14 at 16:32