Solved

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

Posted on 2014-02-12
10
265 Views
Last Modified: 2014-02-12
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>
0
Comment
Question by:badtz7229
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
10 Comments
 
LVL 18

Expert Comment

by:zc2
ID: 39853624
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

0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39853632
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"
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39853657
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
0
Why You Need a DevOps Toolchain

IT needs to deliver services with more agility and velocity. IT must roll out application features and innovations faster to keep up with customer demands, which is where a DevOps toolchain steps in. View the infographic to see why you need a DevOps toolchain.

 

Author Comment

by:badtz7229
ID: 39853760
i need the position() in case there are more <person> then i want to seperate the @type with "/"
0
 

Author Comment

by:badtz7229
ID: 39853779
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>
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39853837
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
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39853842
OK, I did not see your example before posting.
But the approach with the @Type nodeset will give you that
0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 39853930
Yep, I just tested the code and given that all the person nodes are wrapped in a Compl node as the document root, this XSLT gives you what you need

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:template match="/">
        <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>          
    </xsl:template>
</xsl:stylesheet>

Open in new window


with this XML that would be

<?xml version="1.0" encoding="UTF-8"?>
<Compl>
    <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> 
</Compl>

Open in new window

0
 

Author Closing Comment

by:badtz7229
ID: 39854099
thx. that worked.
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39854230
welcome
0

Featured Post

How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article discusses four methods for overlaying images in a container on a web page
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
In this Micro Tutorial viewers will learn how to create a CSS image sprite (In a later tutorial, viewers will learn how to use CSS and HTML to create a navigation menu using this sprite) Open a new Photoshop document with a width of (Icon width)x(N…
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question