Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1148
  • Last Modified:

XSL max/string compare

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
RobertNoble
Asked:
RobertNoble
  • 6
  • 4
3 Solutions
 
Andrei TeodorescuBusiness OwnerCommented:
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
 
RobertNobleAuthor Commented:
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
 
Andrei TeodorescuBusiness OwnerCommented:
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.

 
RobertNobleAuthor Commented:
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
 
Andrei TeodorescuBusiness OwnerCommented:
please provide me with some more info; how are the lists defined in SHP and the source code of your DVWP
0
 
RobertNobleAuthor Commented:
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
 
RobertNobleAuthor Commented:
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
 
RobertNobleAuthor Commented:
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
 
RobertNobleAuthor Commented:
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
 
Andrei TeodorescuBusiness OwnerCommented:
Hi,

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

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now