Need xsl help

Discussion in 'XML' started by Larry Coon, Dec 13, 2005.

  1. Larry Coon

    Larry Coon Guest

    I'm trying to use xsl for the first time, and as with
    any first-time attempt, I'm running into problems.

    I'm trying to transform an XML document into another
    XML document with a slightly different format. Here's
    an example of what the source XML looks like:

    - - - - begin source.xml - - - -

    <?xml version="1.0" encoding="UTF-8"?>

    <result>
    <row>
    <column colname="device" colnum="1">syb0201</column>
    <column colname="physical" colnum="2">/dev/rlv0201</column>
    <column colname="dbname" colnum="3">curric_prod</column>
    <column colname="segname" colnum="4">index</column>
    <column colname="mbytes" colnum="5">500</column>
    </row>
    <row>
    <column colname="device" colnum="1">syb0201</column>
    <column colname="physical" colnum="2">/dev/rlv0201</column>
    <column colname="dbname" colnum="3">reports_prod</column>
    <column colname="segname" colnum="4">system</column>
    <column colname="mbytes" colnum="5">300</column>
    </row>
    </result>

    - - - - end of source.xml - - - -

    (There are many more <row> elements, omitted for this example.

    Here's what I want the target to look like:

    - - - - target.xml - - - -

    <?xml version="1.0" encoding="UTF-8"?>

    <result>
    <row>
    <device colnum="1">syb0201</column>
    <physical colnum="2">/dev/rlv0201</column>
    <dbname colnum="3">curric_prod</column>
    <segname colnum="4">index</column>
    <mbytes colnum="5">500</column>
    </row>
    <row>
    <device colnum="1">syb0201</column>
    <physical colnum="2">/dev/rlv0201</column>
    <dbname colnum="3">reports_prod</column>
    <segname colnum="4">system</column>
    <mbytes colnum="5">300</column>
    </row>
    </result>

    - - - - end of target.xml - - - -

    Here's the xsl I tried using:

    - - - - begin transform.xsl - - - -

    <?xml version="1.0"?>

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

    <xsl:template match = "/">
    <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match = "result">
    <result>
    <xsl:apply-templates/>
    </result>
    </xsl:template>

    <xsl:template match = "row">
    <row>
    <xsl:apply-templates/>
    </row>
    </xsl:template>

    <xsl:template match = "column">
    <xsl:element name = "@colname">
    <xsl:attribute name = "colnum">
    <xsl:value-of select = "@colnum"/>
    </xsl:attribute>

    <xsl:template match = "text()">
    <xsl:value-of select = "."/>
    </xsl:template>
    </xsl:element>
    </xsl:template>
    </xsl:stylesheet>

    - - - - end transform.xsl - - - -

    When I apply the transform, it generates the <result> and <row>
    elements just fine, but it doesn't generate the elements for the
    columns. I thought that this:

    <xsl:template match = "column">
    <xsl:element name = "@colname">
    <xsl:attribute name = "colnum">
    <xsl:value-of select = "colnum"/>
    </xsl:attribute>

    would match a <column> element in the source, create a new
    element in the target where the name of the new element is
    the value of the colname attribute, and the colnum attribute
    is copied verbatim. But when I apply the transform, I get
    stderr output:

    Compiler warnings:
    file:///C:/java/transform.xsl: line 25: You
    cannot call an element '@colname'

    And my output file looks like this:

    - - - - begin out.xml - - - -

    <?xml version="1.0" encoding="UTF-8"?><result>

    <row>
    syb0201
    /dev/rlv0201
    curric_prod
    index
    500
    </row>
    <row>
    syb0201
    /dev/rlv0201
    reports_prod
    system
    300
    </row>
    </result>

    - - - - end of out.xml - - - -

    So it never creates the structure for the column element
    (although it does copy the text inside the element correctly).
    I don't understand the error "You cannot call an element
    @colname," since as I understand it, this simply selects the
    value of the colname attribute (right?).

    If anybody more familiar with xsl than I can point me in the
    right direction, I'd appreciate it.


    Larry Coon
    University of California
    Larry Coon, Dec 13, 2005
    #1
    1. Advertising

  2. Larry Coon

    Larry Coon Guest

    Larry Coon wrote:

    Follow-up: I think I found my own answer. Rather than:

    <xsl:element name = "@colname">

    I needed:

    <xsl:element name = "{@colname}">


    Larry Coon
    University of California
    Larry Coon, Dec 13, 2005
    #2
    1. Advertising

  3. "Larry Coon" <> wrote in message
    news:...

    > - - - - begin source.xml - - - -
    >
    > <?xml version="1.0" encoding="UTF-8"?>
    >
    > <result>
    > <row>
    > <column colname="device" colnum="1">syb0201</column>
    > <column colname="physical" colnum="2">/dev/rlv0201</column>
    > <column colname="dbname" colnum="3">curric_prod</column>
    > <column colname="segname" colnum="4">index</column>
    > <column colname="mbytes" colnum="5">500</column>
    > </row>
    > <row>
    > <column colname="device" colnum="1">syb0201</column>
    > <column colname="physical" colnum="2">/dev/rlv0201</column>
    > <column colname="dbname" colnum="3">reports_prod</column>
    > <column colname="segname" colnum="4">system</column>
    > <column colname="mbytes" colnum="5">300</column>
    > </row>
    > </result>
    >
    > - - - - end of source.xml - - - -



    > - - - - target.xml - - - -
    >
    > <?xml version="1.0" encoding="UTF-8"?>
    >
    > <result>
    > <row>
    > <device colnum="1">syb0201</column>
    > <physical colnum="2">/dev/rlv0201</column>
    > <dbname colnum="3">curric_prod</column>
    > <segname colnum="4">index</column>
    > <mbytes colnum="5">500</column>
    > </row>
    > <row>
    > <device colnum="1">syb0201</column>
    > <physical colnum="2">/dev/rlv0201</column>
    > <dbname colnum="3">reports_prod</column>
    > <segname colnum="4">system</column>
    > <mbytes colnum="5">300</column>
    > </row>
    > </result>
    >
    > - - - - end of target.xml - - - -


    Using an identity transform:

    --begin--

    <?xml version="1.0" encoding="iso-8859-1" ?>
    <xsl:transform version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:template match="column">
    <xsl:element name="{@colname}">
    <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
    </xsl:template>

    <xsl:template match="@colname"/>

    </xsl:transform>

    --end--

    // Magnus
    Magnus Henriksson, Dec 14, 2005
    #3
  4. Larry Coon

    Larry Coon Guest

    Magnus Henriksson wrote:

    > Using an identity transform:


    (rest snipped)

    Thanks!

    I'm now trying to figure out how to copy a comment node from the
    source document to the target document.

    I know I have to use <xsl:comment>, but I don't see how to select
    the comments from the source document. Can you point me the right
    direction?


    Larry Coon
    University of California
    Larry Coon, Dec 15, 2005
    #4
  5. Larry Coon

    Larry Coon Guest

    Magnus Henriksson wrote:

    > Using an identity transform:


    One more question, if I may....what's the correct way to add newlines
    to the result document? I'm getting output that looks like:

    <result><row><column> . . .

    and I want:

    <result>
    <row>
    <column> . . .

    or at least:

    <result>
    <row>
    <column> . . .

    I played with inserting:

    <xsl:text>
    </xsl:text>

    which sort of did what I want, but not reliably. Is there
    a better way to accomplish this? Thanks.


    Larry Coon
    University of California
    Larry Coon, Dec 15, 2005
    #5
  6. Larry Coon wrote:
    > I don't see how to select
    > the comments from the source document.


    Have a look at the XPath specification
    (<http://www.w3.org/TR/xpath#NT-NodeType>):

    comment()
    --
    Johannes Koch
    Spem in alium nunquam habui praeter in te, Deus Israel.
    (Thomas Tallis, 40-part motet)
    Johannes Koch, Dec 15, 2005
    #6
  7. Larry Coon

    Peter Flynn Guest

    Larry Coon wrote:

    > Magnus Henriksson wrote:
    >
    >> Using an identity transform:

    >
    > (rest snipped)
    >
    > Thanks!
    >
    > I'm now trying to figure out how to copy a comment node from the
    > source document to the target document.
    >
    > I know I have to use <xsl:comment>, but I don't see how to select
    > the comments from the source document. Can you point me the right
    > direction?


    <xsl:template match="comment()">
    <xsl:copy/>
    </xsl:template>

    ///Peter
    --
    XML FAQ: http://xml.silmaril.ie/
    Peter Flynn, Dec 16, 2005
    #7
  8. "Larry Coon" <> wrote in message
    news:...

    > One more question, if I may....what's the correct way to add newlines
    > to the result document? I'm getting output that looks like:
    >
    > <result><row><column> . . .
    >
    > and I want:
    >
    > <result>
    > <row>
    > <column> . . .


    This can be controlled with <xsl:eek:utput indent="yes"/> (see
    http://www.w3.org/TR/xslt#output).

    The implementation of this instruction depends on the vendor, so using
    different XSLT processors may result in different indentations (or none at
    all). I would also caution against pretty printing the result tree, as it
    may lead to unforeseen problems (after all, whitespace is significant in
    XML).

    If you want pretty printed results (for e.g. debugging purposes) you can do
    something like this: In your production stylesheet, set <xsl:eek:utput
    indent="no"/>. Then create a second (pretty printing) stylesheet that
    imports your production stylesheet (<xsl:import href="production.xsl"/>. The
    pretty printing stylesheet should then set <xsl:eek:utput indent="yes"/>.

    Because of the import precedence rules, the <xsl:eek:utput/> element in the
    imported stylesheet has lower precedence.

    Something like this:

    --production.xsl-

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:transform version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:eek:utput indent="no"/>

    ...

    </xsl:transform>


    --pretty-production.xsl--

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:transform version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:eek:utput indent="yes"/>

    </xsl:transform>


    // Magnus
    Magnus Henriksson, Dec 16, 2005
    #8
  9. Larry Coon

    Larry Coon Guest

    Magnus Henriksson wrote:

    (snipped)

    Thanks Magnus & Johannes for your help. My output is
    looking the way I want it to now.


    Larry Coon
    University of California
    Larry Coon, Dec 16, 2005
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kevin Flood
    Replies:
    0
    Views:
    1,017
    Kevin Flood
    Sep 8, 2004
  2. Kevin Flood
    Replies:
    1
    Views:
    2,728
    Kevin Flood
    Sep 13, 2004
  3. Klaus Friese
    Replies:
    0
    Views:
    466
    Klaus Friese
    Nov 22, 2004
  4. Replies:
    1
    Views:
    3,595
    A. Bolmarcich
    May 27, 2005
  5. =?iso-8859-1?q?Jean-Fran=E7ois_Michaud?=

    Help with XSL/XSL:FO for producing revision indicator bar in document.

    =?iso-8859-1?q?Jean-Fran=E7ois_Michaud?=, Apr 28, 2006, in forum: XML
    Replies:
    6
    Views:
    572
    =?iso-8859-1?q?Jean-Fran=E7ois_Michaud?=
    May 3, 2006
Loading...

Share This Page