1

I am trying to loop through a node, which in itselt is not a problem. I want to check to see if the selectedLetter matches the first letter of the node, which is working as intended (see code below). The difficulties arise in that I would like to present some alternative text if the conditional "" is not met at least once during the loop, along the lines of "Sorry, no documents begin with that letter". I was thinking about setting a variable i.e. flag in the conditional and check later on if this variable has been set, but from what I have read here, the scope of the variable is restricted and only available within the loop? Can anyone offer any assistance?

Cheers, Taff

<xsl:param name="selectedLetter" select="''"/>
<xsl:key name="docLetter" match="docs" use="substring(text()),1,1)"/>

                <xsl:for-each select="//ad-documents/item">

                    <xsl:sort select="documentName"/>
                    <xsl:variable name="firstLetter" select="upper-case(substring(documentName, 1, 1))"/>

                    <xsl:choose>

                        <xsl:when test="$firstLetter = $selectedLetter">

                            <div class="doc-date">
                                <xsl:if test="upload-date/day &lt; 10">0</xsl:if>
                                <xsl:value-of select="upload-date/day"/>
                                <xsl:text>.</xsl:text>
                                <xsl:if test="upload-date/month &lt; 10">0</xsl:if>
                                <xsl:value-of select="upload-date/month"/>
                                <xsl:text>.</xsl:text>
                                <xsl:value-of select="upload-date/year"/>
                            </div>

                            <div class="doc-link">
                                <a>
                                    <xsl:attribute name="href">
                                        <xsl:choose>
                                            <xsl:when test="isEditableFormDoc/box = 'true'">
                                                #
                                            </xsl:when>
                                            <xsl:otherwise>
                                                <xsl:text>/img/ejbfile/</xsl:text>
                                                <xsl:value-of select="documents/document/@documentName"/>
                                                <xsl:text>?id=</xsl:text>
                                                <xsl:value-of select="documents/document/@src"/>
                                            </xsl:otherwise>
                                        </xsl:choose>      
                                    </xsl:attribute>
                                    <xsl:if test="isEditableFormDoc/box = 'true'">
                                        <xsl:attribute name="target">
                                            <xsl:text>_blank</xsl:text>
                                        </xsl:attribute>
                                    </xsl:if>
                                    <xsl:value-of select="documentName"/>
                                </a>
                            </div>

                            <div class="doc-short-desc">
                                <xsl:apply-templates select="document-short-desc" mode="format"/>
                            </div>

                            <!--<xsl:apply-templates select="//ad-documents/item" mode="filteredDocuments"/>-->
                        </xsl:when>
                    </xsl:choose>

              </xsl:for-each>

EDIT:

XML Example

<ad-documents name="ad-documents" label="Dokumente (limitiert auf 20 pro Seite)">
  <item description="Doc%203" id="1" timestamp="1328525592205">
    <documentName name="documentName" description="Doc%203">Doc 3</documentName>
    <optionalLetter name="optionalLetter" description="c">c</optionalLetter>
    <document-short-desc name="document-short-desc" description="">
      <p>yxf</p>
    </document-short-desc>
    <upload-date name="upload-date" description="">
      <day>24</day>
      <month>2</month>
      <year>2012</year>
    </upload-date>
    <isEditableFormDoc name="isEditableFormDoc" description="">
      <box/>
    </isEditableFormDoc>
    <documents name="documents" description=""/>
  </item>
  <item description="Doc%204" id="2" timestamp="1328525624889">
    <documentName name="documentName" description="Doc%204">Doc 4</documentName>
    <optionalLetter name="optionalLetter" description="z%2Ci%2Cg">z,i,g</optionalLetter>
    <document-short-desc name="document-short-desc" description="">
      <p>asff</p>
    </document-short-desc>
    <upload-date name="upload-date" description="">
      <day>25</day>
      <month>2</month>
      <year>2012</year>
    </upload-date>
    <isEditableFormDoc name="isEditableFormDoc" description="">
      <box/>
    </isEditableFormDoc>
    <documents name="documents" description=""/>
  </item>
  <item description="Doc%201" id="1" timestamp="1328523551639">
    <documentName name="documentName" description="Doc%201">Doc 1</documentName>
    <optionalLetter name="optionalLetter" description="b%2Cc">b,c</optionalLetter>
    <document-short-desc name="document-short-desc" description="">
      <p>Short Desc 1</p>
    </document-short-desc>
    <upload-date name="upload-date" description="">
      <day>9</day>
      <month>2</month>
      <year>2012</year>
    </upload-date>
    <isEditableFormDoc name="isEditableFormDoc" description="">
      <box/>
    </isEditableFormDoc>
    <documents name="documents" description=""/>
  </item>
</ad-documents>
Taff
  • 25
  • 1
  • 5
  • So, how can we guess what the source XML document looks like? Please, edit the question and provide the source XML document (as small as possible) and the exact wanted result. – Dimitre Novatchev May 16 '12 at 12:56

2 Answers2

0

The solution is simple:

Just replace:

 <xsl:for-each select="//ad-documents/item">

with

 <xsl:for-each select=
    "//ad-documents/item
            [$selectedLetter eq upper-case(substring(documentName, 1, 1) ]">

You can add after this xsl:for-each

<xsl:sequence select=
 "'YourErrorMessage'
     [not(//ad-documents/item
                [$selectedLetter eq upper-case(substring(documentName, 1, 1) ]

         )
      ]"
 />
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • @Taff: Please, let me know if this solves your problem or if you still have other problems. – Dimitre Novatchev May 16 '12 at 16:06
  • Hey Dimitre,couldn't seem to get it to work with xsl:sequence. Not sure if it was something to do with the " in the not condition clashing with the " in select, but even when trying with ' or even without I was still getting parse errors, but your first code snippet was enough to guide me to the solution. – Taff May 21 '12 at 14:07
  • @Taff: I am glad my answer was useful. Could you please, *accept* it (by clicking on the check-mark next to the answer)? As for the error -- yes, there is a typo -- just remove the quote in `not("`. And of course, you must have an XSLT 2.0 processor to perform this transformation. – Dimitre Novatchev May 21 '12 at 14:32
0

Thanks to Dimitre, I managed to solve the problem with count()

<xsl:variable name="foundDocs" select="count(//ad-documents/item[$selectedLetter eq upper-case(substring(documentName, 1, 1))])"/>
                <xsl:if test="$foundDocs = 0">
                    <div class="no-documents">
                        <xsl:text>Leider keine Dokumente gefunden</xsl:text>
                    </div>
                </xsl:if>
Taff
  • 25
  • 1
  • 5