Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old May 6th, 2008, 10:16 AM
Registered User
 
Join Date: May 2008
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to Clark Kent
Default XML element with delimited values and XSLT

Hello all,

I've got quite the problem that I just cannot seem to solve (probably because I'm an XSLT noob!)

I've got some source XML in this very simple format:

<document>
    <item>
        <name>Kraft</name>
        <size>10</size>
        <price>5.99</price>
        <market>CA|DDE|US|RTS</market>
    </item>
</document>

and I am using an XSLT style sheet to transform the data into a little bit more structured XML(basically just cosmetic changes). However, one of the things I need to do is parse through the elements with multi-delimited values. In the above example you can see that my element <market> has several values delimited by a "pipe".

For my resulting XML I need the XML above to turn into:

<document>
    <item>
        <name>Kraft</name>
        <size>10</size>
        <price>5.99</price>
        <market>
            <1>CA</1>
            <2>DDE</2>
            <3>US</3>
            <4>RTS</4>
        </market>
    </item>
</document>

I'm looking for XSLT help in order to accomplish change to the <market> element above. Please help!

Thank you!

 
Old May 6th, 2008, 10:45 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Are you using XSLT 2.0?
Then it is easy to split the string with the tokenize function. However elements names starting with a digit are not allowed.
Code:
<xsl:template match="market">
  <xsl:for-each select="tokenize(., '\|')">
    <xsl:element name="el{.}">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:for-each>
</xsl:template>
--
  Martin Honnen
  Microsoft MVP - XML
 
Old May 6th, 2008, 10:52 AM
Registered User
 
Join Date: May 2008
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to Clark Kent
Default

Unfortunately XSLT 2.0 is not an option as I'm using .Net

As far as the element name starting with the number - d'oh! I knew that

:)
 
Old May 6th, 2008, 10:56 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

If you need a 1.0 solution, download the str:tokenize recursive template from www.exslt.org and incorporate it into your stylesheet. But this kind of thing is much easier in 2.0.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old May 6th, 2008, 10:57 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

>Unfortunately XSLT 2.0 is not an option as I'm using .Net

Saxon implements XSLT 2.0 and is available under .NET, so unless you're one of the people who won't touch any software unless Microsoft wrote it, this shouldn't stop you.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
 
Old May 6th, 2008, 11:24 AM
Registered User
 
Join Date: May 2008
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to Clark Kent
Default

Thanks for the replies! I'm looking into the Tokanize template for 1.0!

 
Old May 6th, 2008, 11:26 AM
Registered User
 
Join Date: May 2008
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to Clark Kent
Default

Quote:
quote:Originally posted by mhkay
 If you need a 1.0 solution, download the str:tokenize recursive template from www.exslt.org and incorporate it into your stylesheet. But this kind of thing is much easier in 2.0.
mhkay, I found the template and inserted into my stylesheet but I am getting reference errors. Is there a URL reference I'm missing? I'm getting an error saying that str is not defined.

<xsl:stylesheet version="1.0" extension-element-prefixes="str" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

EDIT *Nevermind, I found the reference.
 
Old May 6th, 2008, 11:46 AM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

Here is an XSLT stylesheet using that template:
Code:
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:str="http://exslt.org/strings"
  xmlns:exsl="http://exslt.org/common"
  version="1.0"
  exclude-result-prefixes="str exsl">

  <xsl:include href="http://www.exslt.org/str/functions/tokenize/str.tokenize.template.xsl"/>

  <xsl:output method="xml" indent="yes"/>

  <xsl:strip-space elements="*"/>

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

  <xsl:template match="market">
    <xsl:copy>
      <xsl:variable name="tokens">
        <xsl:call-template name="str:tokenize">
          <xsl:with-param name="string" select="."/>
          <xsl:with-param name="delimiters" select="'|'"/>
        </xsl:call-template>
      </xsl:variable>
      <xsl:for-each select="exsl:node-set($tokens)/token">
        <m>
          <xsl:value-of select="."/>
        </m>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>
--
  Martin Honnen
  Microsoft MVP - XML
 
Old May 6th, 2008, 02:41 PM
Registered User
 
Join Date: May 2008
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to Clark Kent
Default

I'm having a hard time getting this to work. Here is what I have:

        <xsl:variable name="MarketVar">
           <xsl:call-template name="str:tokenize">
             <xsl:with-param name="string" select="market"></xsl:with-param>
             <xsl:with-param name="delimiters" select="'|'"></xsl:with-param>
           </xsl:call-template>
         </xsl:variable>
        <xsl:for-each select="exsl:node-set($MarketVar)/token">
          <m>
            <xsl:value-of select="."/>
          </m>
        </xsl:for-each>

It's really screwing up my resulting XML file. The file has no data so it's bombing out somehow.
 
Old May 7th, 2008, 05:21 AM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

Follow the instructions at

http://www.exslt.org/str/index.html

namely

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:str="http://exslt.org/strings"
                extension-element-prefixes="str">

<xsl:import href="str.xsl" />

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference





Similar Threads
Thread Thread Starter Forum Replies Last Post
Generating a comma-delimited data in XSLT dude153 XSLT 2 November 30th, 2007 12:12 PM
Write XML element into textbox with XSLT tcstom XSLT 4 July 5th, 2006 04:08 AM
xml element values vakorde XSLT 3 May 2nd, 2006 04:36 AM
Converting XML to XML (making element mandatory) boondocksaint20 XSLT 8 April 28th, 2006 10:54 AM
Update a table with XML element values alavastros XML 1 July 16th, 2004 11:36 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.