Solved

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

Posted on 2013-02-02
7
496 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
Business Impact of IT Communications

What are the business impacts of how well businesses communicate during an IT incident? Targeting, speed, and transparency all matter. Find out more in this infographic.

 
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

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.
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …
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…

734 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