Solved

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

Posted on 2013-02-02
7
490 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
  • 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
Guide to Performance: Optimization & Monitoring

Nowadays, monitoring is a mixture of tools, systems, and codes—making it a very complex process. And with this complexity, comes variables for failure. Get DZone’s new Guide to Performance to learn how to proactively find these variables and solve them before a disruption occurs.

 
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 500 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

Independent Software Vendors: 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

Suggested Solutions

Title # Comments Views Activity
jboss 7.1 start up error 1 63
Output in PHP throwing alignment of data off issue 12 56
TSQL XML Namespaces 7 36
Is online banking safe? 11 87
A short article about problems I had with the new location API and permissions in Marshmallow
If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

749 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