tags:

views:

35

answers:

1

I've got a field in my xml that looks like this (some examples):

<ViolationCharged>VTL0180     0D    0I0</ViolationCharged>
<ViolationCharged>VTL0180-C     02A    0I0</ViolationCharged>
<ViolationCharged>VTL1180     B    0I0</ViolationCharged>

I need to turn it into something that looks like this:

<Violation>VTL180.0D</Violation>
<Violation>VTL180-C.02A</Violation>
<Violation>VTL1180.B</Violation>

Basically, I need to take the first field from that block and remove the leading zeros (if they exist) from the number block, then combine that first field with the second one with a period. I'm a bit of an XSLT noob, but with 2.0, I believe I can do this with analyze-string and a not exceptionally complicated regular expression, however, I can't wrap my head around anything in 1.0 that will work and I'm sort of forced to use what's already in place here.

Any help is of course much appreciated.

+3  A: 

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*" name="identity">
       <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
       </xsl:copy>
 </xsl:template>

 <xsl:template match="text()">
  <xsl:variable name="vNormalized" select="normalize-space()"/>
  <xsl:variable name="vWithDots" select="translate($vNormalized, ' ', '.')"/>

  <xsl:variable name="vFinal" select=
   "concat(substring-before($vWithDots, '.'),
          '.',
          substring-before(substring-after($vWithDots, '.'), '.'))"/>

          <xsl:value-of select="$vFinal"/>
 </xsl:template>
</xsl:stylesheet>

when applied on this XML document:

<t>
    <ViolationCharged>VTL0180     0D    0I0</ViolationCharged>
    <ViolationCharged>VTL0180-C     02A    0I0</ViolationCharged>
    <ViolationCharged>VTL1180     B    0I0</ViolationCharged>
</t>

produces the wanted, correct result:

<t>
    <ViolationCharged>VTL0180.0D</ViolationCharged>
    <ViolationCharged>VTL0180-C.02A</ViolationCharged>
    <ViolationCharged>VTL1180.B</ViolationCharged>
</t>
Dimitre Novatchev
Close, but it doesn't appear to remove the leading zero on the 0180. That make it a lot worse?
Morinar
Just replace in `vFinal` declaration `substring-before($vWithDots, '.')` with `substring(.,1,3),substring(.,5,7)`
Alejandro
That doesn't *quite* work as it would cut off the 1 in the third case. What I ended up doing, however, was merely checking for 'VTL0' (and the other 3 possible things the field can start with) and if it starts that way, I perform the substring similar to what you suggest. Thanks for the help! Definitely put me on the right track.
Morinar
@Morinar: If your first pattern is three letters and four digits you could do: `substring(.,1,3),number(substring(.,4,7))`. If there could be more or less than three letters or four digits: `translate(substring-before($vWithDots, '.'),'1234567890',''),number(translate(substring-before($vWithDots, '.'),'QWERTYUIOPASDFGHJKLZXCVBNM',''))`
Alejandro