?
Solved

XSL Help retieving a node value using the value from another node...

Posted on 2013-02-02
7
Medium Priority
?
504 Views
Last Modified: 2013-02-03
I have an xml file which has a node with a value which I have to use to retrieve a value from another node....the value I must use is from organisationRef (see below) "#id3"

<OrganisationMember id="id2" roleRef="#id35" organisationRef="#id3" memberRef="#id209">

the value I must derive is from Organisation (see below) I use the organisationRef value from the above node to find the Organisation and I need to derive the name value "Copeland North America"

<Organisation id="id3" name="Copeland North America">

I can get the values out of OrganisationMember ok using the following XPath call...

      <xsl:variable name="grp_id">
              <xsl:for-each select="/plm:PLMXML/plm:OrganisationMember">
                    <xsl:if test="@memberRef = $mem_id" >
                        <xsl:value-of select="translate(@organisationRef, '#', ' ')" />
                    </xsl:if>
              </xsl:for-each>
      </xsl:variable>

 The problem is the values cannot be used as individual values....I think the Variable grp_id is all the values combined. So, I tried tokenizing the variable to no avail. I am not even sure if this is the right approach. I will attach the XML and the XSL. I am parsing with Xalan-J.

You can see in the xml I am using a for-each on the User node and this I am sure is what is killing me. In the end I just need an html that looks like the attached. The exception is I need the group field to have the Organisation name not the ID. Any help is greatly appreciated. One other note, I believe this may have to be completely rewritten because I am using the for-each loop on User but I am open for suggestions.
a.xsl
My.xml
fin.htm
0
Comment
Question by:jsprenz1
[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
  • 4
  • 2
7 Comments
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 38847971
The extension stuff didn't work for me so I took that out for testing.

This works for me:
<xsl:variable name="grp_id">
	        <xsl:for-each select="/plm:PLMXML/plm:OrganisationMember[@memberRef = $mem_id]">
	                <xsl:variable name="ref_org"><xsl:value-of select="substring-after(@organisationRef, '#')" /></xsl:variable>
		<xsl:value-of select="/plm:PLMXML/plm:Organisation[@id = $ref_org]/@name" />
	        </xsl:for-each>
	      </xsl:variable>

Open in new window

and instead of temp[1], change the output (back) to:
<td><xsl:value-of select="$grp_id"/></td>

Open in new window

0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 38847979
If you wanted to, you could actually do this without variables:
<td><xsl:value-of select="/plm:PLMXML/plm:Organisation[@id = substring-after(/plm:PLMXML/plm:OrganisationMember[@memberRef = $mem_id]/@organisationRef, '#')]/@name" /></td>

Open in new window

0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 38848551
In case you ever wanted to use the exslt tokenize function there are two things you need to be aware of.
1. it is not supported in Xalan, so you would better use Jeni Tennisons templates
(or use libxslt which is the only processor that supports tokenize)
2. tokenize is not in the common namespace but in the strings namespace
           xmlns:exsl="http://exslt.org/common"
should be
           xmlns:exsl="http://exslt.org/strings"

But you don't need it here. There is actually a lot of variable work that could be simplified.
I will make a suggestion for a lot of improvement in a later post.
But for now, I note that roberts solution only returns one organisation and the PLM model allows to be member of multiple
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 60

Expert Comment

by:Geert Bormans
ID: 38848560
OK, I have cleaned up your stylesheet

1. I have found that you rely on position for linking a Person to a User. The PLM model relates them based on @personRef. There is no reason why the position relation should be correct. I have used a key() to relate them properly
2. Projects. There is no need to get all the different projects in 16 variables. I also saw you did not use activity status. You can do the reference in place, as I have showed in the stylesheet. It takes away all variables, showing the same result. Code cut 60%. Performance increased by a factor. If you need to use activity status or need to limit to 16, tell me, I will change it
3. Organisation. I have used keys for the references and changed the code a bit. I used keys for performance. You are walking up and down the tree unnecessarily. Keys are indexes, major increrase in performance. You now have all the organisations. It is a simple fix to only get the  distinct ones, or only the first if you which. Even if you only need one, I recommend this approach
0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 2000 total points
ID: 38848561
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:plm="http://www.plmxml.org/Schemas/PLMXMLSchema" >
	<xsl:output method="html" indent="yes"/>
	
	<!--GLOBAL VARIABLES-->
	
	<xsl:key name="project" match="plm:PLMXML/plm:Project" use="@id"/>
	<xsl:key name="person" match="plm:PLMXML/plm:Person" use="@id"/>
	<xsl:key name="org" match="plm:PLMXML/plm:Organisation" use="@id"/>
	<xsl:key name="org-member" match="plm:PLMXML/plm:OrganisationMember" use="substring-after(@memberRef, '#')"/>
	
	<xsl:template match="plm:PLMXML">
		<html>
			<body>
				<h2 align="center">EMR User Report </h2>
				<table border="3" align="center">
					<tr>
						<tr align="center" bgcolor="#B8CFEP">
							<th>Person</th>
							<th>User Name</th>
							<th>Organization</th>
							<th>Group</th>
							<th>Nationality</th>
							<th>IP Clearance</th>
							<th>Gov Clearance</th>
							<th>Geography</th>
							<th>Status</th>
							<th>Last Login</th>
							<th>Project Name/ID - Status</th>		  
						</tr>
					</tr>
					<xsl:apply-templates select="plm:User"/>
				</table>
			</body>
		</html>
		
	</xsl:template>
	
	<xsl:template match="plm:User">
		
		<xsl:variable name="num1" select="position()"/>
		<xsl:variable name="this-person" select="key('person', substring-after(@personRef, '#'))"/>
		<xsl:variable name="per_org" select="$this-person/plm:UserData/plm:UserValue[@title = 'PA6']/@value"/>
		
		<xsl:variable name="mem_id" select="concat('#',@id)"/>
		<xsl:variable name="mem_id1" select="@id"/>
		
		<xsl:variable name="grp_obj">
			<xsl:for-each select="/plm:PLMXML/plm:Organisation">
				<xsl:value-of select="concat('#',@id)" />
			</xsl:for-each>
		</xsl:variable>
		
		<xsl:variable name="grp_obj1">
			<xsl:for-each select="/plm:PLMXML/plm:Organisation">
				<xsl:value-of select="@name" />
			</xsl:for-each>
		</xsl:variable>
		
		
		<xsl:variable name="usr_id" select="@userId"/>
		<xsl:variable name="last_login" select="plm:UserData/plm:UserValue[@title='last_login_time']/@value"/>
		<xsl:variable name="nationality" select="plm:UserData/plm:UserValue[@title='nationality']/@value"/>
		<xsl:variable name="geography" select="plm:UserData/plm:UserValue[@title='geography']/@value"/>
		<xsl:variable name="ip_clearance" select="plm:UserData/plm:UserValue[@title='ip_clearance']/@value"/>
		<xsl:variable name="gov_clearance" select="plm:UserData/plm:UserValue[@title='gov_clearance']/@value"/>
		<xsl:variable name="status" select="plm:UserData/plm:UserValue[@title='status']/@value"/>
		<xsl:variable name="per" select="$this-person/@lastName"/>
		
		
		
		<tr>
			<td><xsl:value-of select="$per"/></td>
			<td><xsl:value-of select="$usr_id"/></td>
			<td><xsl:value-of select="$per_org"/></td>
			
			<td>
				<xsl:for-each select="key('org-member', @id)">
					<xsl:value-of select="key('org', substring-after(@organisationRef, '#'))/@name"/>
					<xsl:text> </xsl:text>
				</xsl:for-each>
			</td>

			<td><xsl:value-of select="$nationality"/></td>
			<td><xsl:value-of select="$ip_clearance"/></td>
			<td><xsl:value-of select="$gov_clearance"/></td>
			<td><xsl:value-of select="$geography"/></td>
			<td><xsl:value-of select="$status"/></td>
			<td><xsl:value-of select="$last_login"/></td>
			<td>
				
				<xsl:for-each select="plm:UserData/plm:UserValue/plm:UserList/plm:Item">
					<xsl:if test="not(position() = 1)">
						<br />
					</xsl:if>
					<xsl:value-of select="position()"/>
					<xsl:text>) </xsl:text>
					<xsl:value-of select="key('project', @value)/@name "/>
					<xsl:text> / </xsl:text>
					<xsl:value-of select="key('project', @value)/@projectId "/>
				</xsl:for-each>
			</td>
		</tr>
		
	</xsl:template>
	
</xsl:stylesheet>

Open in new window

0
 

Author Comment

by:jsprenz1
ID: 38848681
Absolutely awesome! I am self taught and learned by necessity. What you have shown me here I will use many times over. I actually tried keys but applied it incorrectly. You are the best!
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 38848898
Welcome
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
Many times as a report developer I've been asked to display normalized data such as three rows with values Jack, Joe, and Bob as a single comma-separated string such as 'Jack, Joe, Bob', and vice versa.  Here's how to do it. 
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
Progress

800 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