1

From the following xml, I read the Version attribute.

<BatchTable>
  <UUThref
    SocketIndex='0 - CCM'
    UUTResult='Passed'
    URL='C:\OverrideCallbacks_BatchReport[4 16 2012][5 44 41 PM].xml'
    FileName='OverrideCallbacks_BatchReport[4 16 2012][5 44 41 PM].xml'
    ECAFailCount='1'
    Version='StationPartNumber=55555 StationSerialNumber=2222 TPSPartNumber=1234'/>
</BatchTable>

The value in the Version attribute is dynamic and user can add any length of strings. How can I split the values and display them on separate rows. So that it displays like this

StationPartNumber=55555
StationSerialNumber=2222
TPSPartNumber=1234

Currently on reading the version value it displays as:

StationPartNumber=55555 StationSerialNumber=2222 TPSPartNumber=1234

If any special character is required to be added between the values then I can have the user ensure it is added so that splitting can be easier. Currently "\n" is being added between concatenation but xsl seems to pick the values and remove any white spaces.

Philip Kendall
  • 4,304
  • 1
  • 23
  • 42
rkk
  • 153
  • 1
  • 1
  • 6
  • http://stackoverflow.com/questions/584082/xslt-best-way-to-split-and-render-comma-separated-text-as-html will probably point you in the right direction. – Philip Kendall Apr 17 '12 at 18:46

2 Answers2

0

DevNull asked the key question here - some things are real easy in XSLT 2.0 while requiring a lot of effort in XSLT 1.0 - see below for a solution in XSLT 2.0, in essence making use of the tokenize() funcion:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="UUThref">
        <root>
            <xsl:variable name="test" select="tokenize(@Version, '\s+')"/>
            <xsl:for-each select="$test">
                <w><xsl:value-of select="."/></w>
            </xsl:for-each>
        </root>
    </xsl:template>
</xsl:stylesheet>

gives

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <w>StationPartNumber=55555</w>
    <w>StationSerialNumber=2222</w>
    <w>TPSPartNumber=1234</w>
</root>

Explanation: \s+ stands for any non-zero number of consecutive whitespaces (space, CR, LF or tab).
The tokenize() function creates a node-set comprised of the strings resulting from splitting the text value based on the regular expression delimiter supplied.
This node-set can be looped over by xsl:for-each.

Maestro13
  • 3,656
  • 8
  • 42
  • 72
0

This is quite simple to do in XSLT 1.0 (and can be produced even with a single XPath expression):

Just use:

translate(normalize-space(/*/*/@Version), ' ', '&#xA;')

Here is the complete transformation -- simpler and shorter than the posted XSLT 2.0 solution -- no xsl:variable, no xsl:for-each:

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

 <xsl:template match="UUThref">
  <xsl:value-of select=
   "translate(normalize-space(/*/*/@Version), ' ', '&#xA;')"/>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the provided XML document:

<BatchTable>
    <UUThref
      SocketIndex='0 - CCM'
            UUTResult='Passed'
          URL='C:\OverrideCallbacks_BatchReport[4 16 2012][5 44 41 PM].xml'
            FileName='OverrideCallbacks_BatchReport[4 16 2012][5 44 41 PM].xml'
            ECAFailCount='1'
            Version='StationPartNumber=55555 StationSerialNumber=2222 TPSPartNumber=1234'/>
</BatchTable>

the wanted, correct result is produced:

StationPartNumber=55555
StationSerialNumber=2222
TPSPartNumber=1234

Explanation:

Appropriate use of the XPath functions normalize-space() and translate()

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431