Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

XSL max/string compare

Posted on 2009-07-14
10
Medium Priority
?
1,147 Views
Last Modified: 2013-11-18
So I've got a SharePoint list of items, some of which have a Comment and all of which are associated with a Step.
The Step field is essentially a lookup on another table's column which incorporates the sort value followed by the step name.

I need to pull only the valid Comment associated with the highest sort value embedded in the Step

Problem is that the comments are not always present, and the steps are not always in the same order as the IDs, so position() is out.

My last attempt with a xsl:sort is in the CODE section below.  The substring-before(substring-after( part filters out empty comments (<div></div>)

Any Ideas?
<xsl:for-each select="$Dates[substring-before(substring-after(@Comment,'&gt;'),'&lt;') !=''][1]">
	<xsl:sort select=. data-type="text" order=descending/>
	<xsl:value-of select="substring-before(substring-after(@Comment,'&gt;'),'&lt;')"/>
</xsl:for-each>

Open in new window

0
Comment
Question by:RobertNoble
[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
  • 4
10 Comments
 
LVL 11

Assisted Solution

by:Andrei Teodorescu
Andrei Teodorescu earned 480 total points
ID: 24859447
Please provide more code and also a simple representation of your data
And what do you intend with select="$Dates[substring-before(substring-after(@Comment,'>'),'<') !=''][1]"

if you want to test for a variable if is empty or not, in your case:
<xsl:if test="substring-before(substring-after(@Comment,'>'),'<')">
0
 

Author Comment

by:RobertNoble
ID: 24860148
Below is what the code looks like now.  It's functional, but pulls up ALL comments instead of only the most 'recent' one.

You're right, the != '' at the end of the test and for-each can be dropped without affecting the outcome.

If i'm not mistaken, the XSLT receives the data from 3 sharepoint lists in the following (abbreviated) forma, where the 3rd references the other 2t:

<Packages>
      <Rows>
            <Row>
                  <Package>
                        <PackageName>A</PackageName>
                  </Package>
                  <Package>
                        <PackageName>B</PackageName>
                  </Package>
                  <Package>
                        <PackageName>C</PackageName>
                  </Package>
            </Row>
      </Rows>
</Packages>
<ProcessSteps>
      <Rows>
            <Row>
                  <Step>
                        <StepName>1 - x</StepName>
                  </Step>
                  <Step>
                        <StepName>2 - y</StepName>
                  </Step>
                  <Step>
                        <StepName>3 - z</StepName>
                  </Step>
            </Row>
      </Rows>
</ProcessSteps>
<Dates>
      <Rows>
            <Row>
                  <Date>
                        <Package>A</Package>
                        <Step>1 - x</Step>
                        <Comment>blah 1</Comment>
                  </Date>
                  <Date>
                        <Package>A</Package>
                        <Step>2 - y</Step>
                        <Comment>blah 2</Comment>
                  </Date>
                  <Date>
                        <Package>B</Package>
                        <Step>1 - x</Step>
                        <Comment>blah 3</Comment>
                  </Date>
            </Row>
      </Rows>
</Dates>

Basically at the end the row (for-each package) I want to display the comment whose step index (before the '-') is highest.
My current code will give me, in the case of Package A: "blah 1 blah 2" when I want only "blah 2"

* there is more data in all of the lists, but these fields are the ones used in this part of the stylesheel.
<xsl:choose>
	<xsl:when test="count($Dates[@Package = $Pkg and substring-before(substring-after(@Comment,'&gt;'),'&lt;')])">
		<xsl:for-each select="$Dates[@Package = $Pkg and substring-before(substring-after(@Comment,'&gt;'),'&lt;')]">
			<xsl:value-of select="substring-before(substring-after(@Comment,'&gt;'),'&lt;')"/><br/>
		</xsl:for-each>
	</xsl:when>
	<xsl:otherwise>
		-<!-- NO VALUE TEXT HERE -->
	</xsl:otherwise>
</xsl:choose>

Open in new window

0
 
LVL 11

Assisted Solution

by:Andrei Teodorescu
Andrei Teodorescu earned 480 total points
ID: 24865125
you still need to sort, but you have to sort before making the test
I still don't get it; the DVWP is showing data from a list or from an aggregate of 3 lists? You said that some columns are lookup type...
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:RobertNoble
ID: 24872013
For the sort, idk how to get it to grab the first element only... using [1] grabs the first element before sorting the data.
You're correct, The data source is joined, and was created in SPD 2007.  
The reason is that the row headers are in one list, the column headers in another, and the data in a 3rd list for a pseud-franken-crosstab view.
Maybe using a siblings-type function or ddwrt:max could be helpful? But I've no experience or idea how to use these, and have not had time to look it up yet.
0
 
LVL 11

Expert Comment

by:Andrei Teodorescu
ID: 24872120
please provide me with some more info; how are the lists defined in SHP and the source code of your DVWP
0
 

Author Comment

by:RobertNoble
ID: 24879193
here's the declarations of the variables from the previous code.

what do you mean "how are the lists defined?"  I setup a joined datasource in SPD 2007 with the fields I needed for the view.
// Defined at the top of the <XSL>
<xsl:variable name="Dates" select="/dsQueryResponse/RFPDates2/Rows/Row"/>
// Defined at the beginning of each <TR> before calling the date-calling template
<xsl:with-param name="Pkg" select="@Package_x002e_FullName"/>
<!-- -->
<xsl:choose>
        <xsl:when test="count($Dates[@Package = $Pkg and substring-before(substring-after(@Comment,'&gt;'),'&lt;')])">
                <xsl:for-each select="$Dates[@Package = $Pkg and substring-before(substring-after(@Comment,'&gt;'),'&lt;')]">
                        <xsl:value-of select="substring-before(substring-after(@Comment,'&gt;'),'&lt;')"/><br/>
                </xsl:for-each>
        </xsl:when>
        <xsl:otherwise>
                -<!-- NO VALUE TEXT HERE -->
        </xsl:otherwise>
</xsl:choose>

Open in new window

0
 

Author Comment

by:RobertNoble
ID: 24879213
I'm basically iterating through the parent lists for each of the packages and steps, since there is not necessarily a date item which matches each pkg/step pair, and need blank space to be present when this is the case.
0
 

Author Comment

by:RobertNoble
ID: 24895023
My latest thought was to use ddwrt:max() on the lookup value and test if it matches the current value to display only th highest value.  The pseudocode is commented out cause I can't seem to get it to work properly.

The datestep field is a lookup to another list, where it combined a sort value and a title.  I've tried using substring to extract only the number and convert it back to an int with number() to apply max() but with no success.
<xsl:when test="count($Dates[@Package = $Pkg and substring-before(substring-after(@Comment,'&gt;'),'&lt;')])">
     <xsl:for-each select="$Dates[@Package = $Pkg and substring-before(substring-after(@Comment,'&gt;'),'&lt;')]">
<!-- If this->datestep = max(datestep) then do the following display -->
          <xsl:value-of select="substring-before(substring-after(@Comment,'&gt;'),'&lt;')"/><br/>
     </xsl:for-each>
</xsl:when>

Open in new window

0
 

Accepted Solution

by:
RobertNoble earned 0 total points
ID: 24895100
I've got it.  for future reference.

The key is taking only the first element AFTER sorting the data.  using a [1] in the for-each doesn't work, because the data only gets sorted after that condition is filled.

by keeping only position() = 1 using and if clause after sorting descending, only the highest-value step is kept (since the step name is prefixed with a sort index)

Code Below
<xsl:when test="count($Dates[@Package = $Pkg and substring-before(substring-after(@Comment,'&gt;'),'&lt;')])">
	<xsl:for-each select="$Dates[@Package = $Pkg and substring-before(substring-after(@Comment,'&gt;'),'&lt;')]">
	<xsl:sort select="@DateStep" order="descending"/>
		<xsl:if test="position() = 1">
			<xsl:value-of select="substring-before(substring-after(@Comment,'&gt;'),'&lt;')"/>
		</xsl:if>
	</xsl:for-each>
</xsl:when>

Open in new window

0
 
LVL 11

Expert Comment

by:Andrei Teodorescu
ID: 24895142
Hi,

Sorry, but I had other things over my head during the past days; glad you found your answer.
0

Featured Post

 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

Question has a verified solution.

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

JavaScript has plenty of pieces of code people often just copy/paste from somewhere but never quite fully understand. Self-Executing functions are just one good example that I'll try to demystify here.
Originally, this post was published on Monitis Blog, you can check it here . In business circles, we sometimes hear that today is the “age of the customer.” And so it is. Thanks to the enormous advances over the past few years in consumer techno…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)

722 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