Am I the first child using an if question

Discussion in 'XML' started by Efi Merdler, Feb 18, 2007.

  1. Efi Merdler

    Efi Merdler Guest

    Hi,
    I have an xml file with the following structure:
    <Dictionary>
    ....
    <Nested>
    <Entry>
    ....
    </Entry>
    <Entry>
    ....
    </Entry>
    </Nested>
    <Entry>
    </Entry>
    </Dictionary>

    I want to iterate over all entries and print them however there is a
    special printing for entries that reside in <Nested> tags and are not
    the first one.

    I'm using the following code:
    <xsl:for-each select="//Entry">
    <p>
    <!--Check if entry is part of a nested entry.-->
    <xsl:if test="name(..)='Nested' and position() > 1">
    <xsl:text>Print:123456</xsl:text>
    </xsl:if>

    The name(..)='Nested' part is working however the position part does
    not, I tried to find some info on the subject with no luck.

    Do you have an idea ?

    Thank,
    Efi
    Efi Merdler, Feb 18, 2007
    #1
    1. Advertising

  2. Efi Merdler

    roy axenov Guest

    On Feb 18, 6:01 pm, "Efi Merdler" <> wrote:
    > I have an xml file with the following structure:
    > <Dictionary>
    > ...
    > <Nested>
    > <Entry>
    > ...
    > </Entry>
    > <Entry>
    > ...
    > </Entry>
    > </Nested>
    > <Entry>
    > </Entry>
    > </Dictionary>
    >
    > I want to iterate over all entries and print them however
    > there is a special printing for entries that reside in
    > <Nested> tags and are not the first one.
    >
    > I'm using


    [for-eachs and ifs]

    > The name(..)='Nested' part is working however the
    > position part does not,


    Of course it doesn't. It returns the position in the
    node-set.

    > I tried to find some info on the subject with no luck.


    Well, here's some info on the subject: you're doing it all
    wrong anyway. Think about your transformations in terms of
    node-sets and templates.

    <xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="Dictionary">
    <result>
    <xsl:apply-templates/>
    </result>
    </xsl:template>
    <xsl:template match="Nested">
    <xsl:apply-templates select="Entry[1]"/>
    </xsl:template>
    <xsl:template match="Entry">
    <xsl:call-template name="Entry"/>
    </xsl:template>
    <xsl:template
    match="Nested/Entry[not(preceding-sibling::Entry)]">
    <xsl:call-template name="Entry"/>
    <xsl:apply-templates
    select="following-sibling::Entry"/>
    </xsl:template>
    <xsl:template
    match="Nested/Entry[preceding-sibling::Entry]">
    <special-entry>
    <xsl:apply-templates/>
    </special-entry>
    </xsl:template>
    <xsl:template name="Entry">
    <normal-entry>
    <xsl:apply-templates/>
    </normal-entry>
    </xsl:template>
    </xsl:stylesheet>

    --
    roy axenov
    roy axenov, Feb 18, 2007
    #2
    1. Advertising

  3. Efi Merdler

    Peter Flynn Guest

    Efi Merdler wrote:
    > Hi,
    > I have an xml file with the following structure:
    > <Dictionary>
    > ...
    > <Nested>
    > <Entry>
    > ...
    > </Entry>
    > <Entry>
    > ...
    > </Entry>
    > </Nested>
    > <Entry>
    > </Entry>
    > </Dictionary>
    >
    > I want to iterate over all entries and print them however there is a
    > special printing for entries that reside in <Nested> tags and are not
    > the first one.
    >
    > I'm using the following code:
    > <xsl:for-each select="//Entry">


    Don't use for-each unless you mean it (ie you want to process the
    elements out of order or out of context).

    If the Entry elements are already in order, then a template matching
    them is all you need. If you want to sort them, however, or if you're
    already processing them in document order elsewhere in your XSLT and you
    now need to handle them again for some other reason, then for-each will
    do it.

    > <p>
    > <!--Check if entry is part of a nested entry.-->
    > <xsl:if test="name(..)='Nested' and position() > 1">
    > <xsl:text>Print:123456</xsl:text>
    > </xsl:if>
    >
    > The name(..)='Nested' part is working however the position part does
    > not, I tried to find some info on the subject with no luck.


    If Entry is the context node, then

    <xsl:if test="parent::Nested and count(preceding-sibling::Entry)>0">
    ...
    </xsl:if>

    will detect if the Entry is inside a Nested element and this is not the
    first Entry of its group. The position() function is problematic because
    it returns the position in the node-set, which may or may not be the
    position in the markup. This is a usability error in XSL: position()
    really ought to have been called node-position(), and position() should
    have been defined with its expected meaning of "position in markup".

    ///Peter
    --
    XML FAQ: http://xml.silmaril.ie/
    Peter Flynn, Feb 18, 2007
    #3
  4. Efi Merdler

    Efi Merdler Guest

    > Don't use for-each unless you mean it (ie you want to process the
    > elements out of order or out of context).
    >
    > If the Entry elements are already in order, then a template matching
    > them is all you need. If you want to sort them, however, or if you're
    > already processing them in document order elsewhere in your XSLT and you
    > now need to handle them again for some other reason, then for-each will
    > do it.
    >
    > ///Peter
    > --
    > XML FAQ: http://xml.silmaril.ie/


    Thanks,
    One more question, when using template matching only once will the
    xslt engine run it in a loop when there are several matches.

    For example:
    <ExampleCtn>
    <Example>He abandoned his family.</Example>
    <Example>She was afraid of being abandoned.</Example>
    </ExampleCtn>

    <xsl:template match="ExampleCtn">
    <xsl:text>:</xsl:text>
    <xsl:value-of select="Example"/>
    </xsl:template>

    will value-of run in a loop on all the Example tag ?

    Thanks,
    Efi
    Efi Merdler, Feb 19, 2007
    #4
  5. Efi Merdler

    Guest

    Please don't quote the sigs and don't remove the
    attributions.

    On Feb 19, 11:44 am, "Efi Merdler" <>
    wrote:
    > > Don't use for-each unless you mean it (ie you want to
    > > process the elements out of order or out of context).


    For that matter, xsl:apply-templates works just nice with
    xsl:sort, too. In my opinion, the rule of the thumb is:
    don't use for-each unless you're dead certain you're not
    pointing it at your foot. (Which you normally are.)

    > One more question, when using template matching only once
    > will the xslt engine run it in a loop when there are
    > several matches.


    Not in a loop, there's no guaranteed order-of-execution.
    But yes, if you *are* using template matching, the XSLT
    processor naturally will apply templates to every node in
    the node-set you've provided.

    > <ExampleCtn>
    > <Example>He abandoned his family.</Example>
    > <Example>She was afraid of being abandoned.</Example>
    > </ExampleCtn>
    >
    > <xsl:template match="ExampleCtn">
    > <xsl:text>:</xsl:text>
    > <xsl:value-of select="Example"/>
    > </xsl:template>
    >
    > will value-of run in a loop on all the Example tag ?


    Why don't you stuff it in your XSLT processor and see what
    happens? No, it's won't 'run in a loop' or anything like
    that, because you're most emphatically *not* using template
    matching in this example. Replace value-of with
    apply-templates.

    --
    Pavel Lepin
    , Feb 19, 2007
    #5
    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. bhchng
    Replies:
    0
    Views:
    642
    bhchng
    Jan 13, 2004
  2. davout
    Replies:
    0
    Views:
    539
    davout
    Apr 18, 2004
  3. leon
    Replies:
    0
    Views:
    421
  4. Jeff Rodriguez
    Replies:
    23
    Views:
    1,083
    David Schwartz
    Dec 9, 2003
  5. Tony Young
    Replies:
    3
    Views:
    309
    Daniel T.
    Mar 26, 2006
Loading...

Share This Page