Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > Am I the first child using an if question

Reply
Thread Tools

Am I the first child using an if question

 
 
Efi Merdler
Guest
Posts: n/a
 
      02-18-2007
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

 
Reply With Quote
 
 
 
 
roy axenov
Guest
Posts: n/a
 
      02-18-2007
On Feb 18, 6:01 pm, "Efi Merdler" <(E-Mail Removed)> 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"
xmlnssl="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

 
Reply With Quote
 
 
 
 
Peter Flynn
Guest
Posts: n/a
 
      02-18-2007
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/
 
Reply With Quote
 
Efi Merdler
Guest
Posts: n/a
 
      02-19-2007
> 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

 
Reply With Quote
 
p.lepin@ctncorp.com
Guest
Posts: n/a
 
      02-19-2007
Please don't quote the sigs and don't remove the
attributions.

On Feb 19, 11:44 am, "Efi Merdler" <(E-Mail Removed)>
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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Parent first or child first? (a class structure question) Tony Young C++ 3 03-26-2006 12:59 AM
restrict the value of one child based on value from another child leon XML 0 09-27-2005 03:32 PM
EJB: How to delete child entries from a parent-child CMR one-to-many relationship? davout Java 0 04-18-2004 07:02 PM
[HELP] Why the child window reopen a new child window ? bhchng ASP .Net 0 01-13-2004 07:17 AM
How do I: Main thread spawn child threads, which child processes...control those child processes? Jeff Rodriguez C Programming 23 12-09-2003 11:06 PM



Advertisments