Link to home
Start Free TrialLog in
Avatar of tesmc
tesmcFlag for United States of America

asked on

XSL: How do I use "and" operator to compare a position and if node exist

How do I use "and" operator to compare a position and if node exist

For example I have following input
<Compl>
      <person Type="ONE">
            <Name>
                  <Fname>SMITH</Fname>
                  <Lname>JOHN</Lname>
            </Name>
            <misc Type="TWO>
                  <Fname>SMITH</Fname>
                  <Lname>JAkE</Lname>
            </misc>
      </person>
</Compl>

And I want output to be ONE/TWO

I have following code
<xsl:for-each select="Compl/person">
      <xsl:value-of select="./@Type"/>
      <xsl:if test="position() != last() and misc">
            <xsl:value-of select="'/'"/>
      </xsl:if>
</xsl:for-each>
Avatar of zc2
zc2
Flag of United States of America image

Yes, you can check a node existence just by mentioning its name in the test string.

Here's an example with the following improvements:
1) Use templates instead of for-each
2) Use <xsl:text> instead of <xsl:value-of select="'/'"/>
 I'm not sure, what's your goal besides printing out ONE/TWO, so I've removed that "position() != last()" test.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="/">
		<xsl:apply-templates select="Compl/person"/>
	</xsl:template>
	
	<xsl:template match="person|misc">
		<xsl:value-of select="@Type"/>
	      <xsl:if test="misc">
	      	<xsl:text>/</xsl:text>
            <xsl:apply-templates select="misc"/>
	      </xsl:if>
 	</xsl:template>
</xsl:stylesheet>

Open in new window

That is exacxtly how you need to use "and"

But I think you want more than that

you need a
<xsl:value-of select="misc/@Type"/>
too
for the "Two"
Maybe you were thinking in terms of

<xsl:for-each select="Compl/person/@Type | Compl/person/misc/@Type">
      <xsl:if test="not(position() = 1)">
            <xsl:text>/</xsl:text>
      </xsl:if>
      <xsl:value-of select="."/>
</xsl:for-each> 

Open in new window


is making the Type attributes the selected node-set
Avatar of tesmc

ASKER

i need the position() in case there are more <person> then i want to seperate the @type with "/"
Avatar of tesmc

ASKER

in this example, i'd want CCC/AAA/III/AAA

            <person Type="CCC">
                  <Name>
                        <Fname>TEMP</Fname>
                        <Lname>ANYTHING</Lname>
                  </Name>
            </person>
            <person Type="AAA">
                  <Name>
                        <Fname>TEMP</Fname>
                        <Lname>ANYTHING</Lname>
                  </Name>
                  <misc Type="III">
                        <Fname>TEMP</Fname>
                        <Lname>ANYTHING</Lname>
                  </misc>
            </person>
            <person Type="AAA">
                  <Name>
                        <Fname>TEMP</Fname>
                        <Lname>ANYTHING</Lname>
                  </Name>
            </person>
OK, but you have the "two" in the misc/@Type inside Person,
that is what caused my comment
So you will need a "/" between Types inside the same person and between persons,
hence my suggestion to collect the nodest of wanted @Type attributes
OK, I did not see your example before posting.
But the approach with the @Type nodeset will give you that
ASKER CERTIFIED SOLUTION
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of tesmc

ASKER

thx. that worked.