On Sat, 2005-06-25 at 15:25 +0000, Al Bean wrote:
Thanks, Sam.
I now have a better understanding of the difference between preceding and
preceding-sibling. And I see how that works whereas my attempt did not.
Also, one of my big mistakes was using
attrib[(_at_)name='Names']/rs/row/@firstname rather than just row/@firstname
as
you pointed out. Thanks.
Ive extended my problem now to include more than one attribute and Ive run
into trouble, again. Im not sure if it is because I dont understand the
specifics of logical operators in XPath or the specifics of
preceding-sibling. (probably both :-) though)
Now I would like to test against firstname AND lastname.
(so I would like to have the second product node in my out to be:
Sam
Ron
Sam
Because each Sam has a different last name.)
These test fail:
<xsl:if test=" not(@firstname=preceding-sibling::row/@firstname) and
not(@ln=preceding-sibling::row/@ln) ">
<xsl:if test=" not(@firstname=preceding-sibling::row/@firstname and
@ln=preceding-sibling::row/@ln) ">
I dont see why these should fail. It makes sense that if one of these
fails the other should since they are logically equivalent.
Chris points out these aren't logically equivalent. not(P) and not(Q) is
not(P or Q).
But I do see why
this logic fails, basically what I (think I) am saying is if the current row
matches a previous siblings lastname AND first name then reject it. How do
I check against two (or more) attributes?
You don't want to search independently for a node that matches the
firstname of the current node and then a node that matches the lastname
of the current node. You want to know if there is one node that matches
both first and last names of the current node. You need something like:
not(preceding-sibling::row
[(_at_)firstname=current()/@firstname]
[(_at_)ln=current()/@ln])
sdc
-------------------------------------
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:ns="http://w.ns.c/ns/prod/">
<xsl:template match="/">
<Products>
<xsl:apply-templates/>
</Products>
</xsl:template>
<xsl:template match="product">
<Product>
<Names>
<xsl:apply-templates mode="XXX"
select="attrib[(_at_)name='Names']/rs/row"/>
</Names>
</Product>
</xsl:template>
<xsl:template mode="XXX" match="attrib[(_at_)name='Names']/rs/row">
<xsl:if test=" not(@firstname=preceding-sibling::row/@firstname) and
not(@ln=preceding-sibling::row/@ln) ">
<name>
<xsl:value-of select="@firstname"/>
</name>
</xsl:if>
</xsl:template>
</xsl:transform>
-------------------------------------
<prods>
<product>
<attrib name="P">product 1</attrib>
<attrib name="Names">
<rs>
<row ln="xxx" firstname="Bill"/>
<row ln="xxx" firstname="Bill"/>
</rs>
</attrib>
</product>
<product>
<attrib name="P">product 2</attrib>
<attrib name="Names">
<rs>
<row ln="qqq" firstname="Sam"/>
<row ln="xxx" firstname="Ron"/>
<row ln="xxx" firstname="Sam"/>
<row ln="xxx" firstname="Ron"/>
</rs>
</attrib>
</product>
<product>
<attrib name="P">product 3</attrib>
<attrib name="Names">
<rs>
<row ln="xxx" firstname="Ron"/>
<row ln="xxx" firstname="Sam"/>
<row ln="xxx" firstname="Joe"/>
<row ln="xxx" firstname="Sam"/>
</rs>
</attrib>
</product>
</prods>
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--