Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 18:57
    Jonas Eriksson
    0

    (not so) funny xslt-error with 'key' and 'for-each'

    This error must be because of some error in my node-structure, or what?

    I have a xslt for a dropdown that are supposed to write a list of cities where companies are located, and every city only once (like sql select distinct).

      <xsl:key name="nodes-by-City" match="node" use="data [@alias='City']" />
      <xsl:template match="/">
    
        <select id="location" name="location">
          <option value="0">Choose location</option>
          <xsl:for-each select="umbraco.library:GetXmlNodeById($companiesRoot)/node [count(. | key('nodes-by-City', data [@alias='City'])[1]) = 1]">
            <xsl:sort select="data [@alias='City']" lang="sv" />
            <option value="{data [@alias='City']}">
              <xsl:value-of select="data [@alias='City']" />
            </option>
          </xsl:for-each>
        </select>
    
      </xsl:template>

    I works well except for the fact it excludes "Stockholm" (!). There are companies with City='Stockholm' I can assure you, but why does my XSLT not catch that?

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 19:08
    Jonas Eriksson
    0

    Huh!! I changed the city to "Stoockholm" and that showed up in the drop-down. This sure is a strange one!

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 19:10
    Jonas Eriksson
    0

    Now I know you start to doubt my sanity, or my eyes at least, but I changed back to Stockholm, and *gone*, the capitol of Sweden just wont show up in that list.

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 19:13
    Jonas Eriksson
    0

    aah, perhaps that '=1' is wrong... :-p

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 19:21
    Jonas Eriksson
    0

    Nope... Here's the point where I leave XSLT for this macro and add some .NET-code instead. :-o

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 19:35
    Jonas Eriksson
    0

    Better looking solution:

      <xsl:template match="/">
    
        <select id="location" name="location">
    
          <option value="0">Välj stad</option>
          <xsl:for-each select="umbraco.library:GetXmlNodeById($companiesRoot)/node [not(./data [@alias='City']=preceding::data [@alias='City'])]">
            <xsl:sort select="data [@alias='City']" lang="sv" />
            <option value="{data [@alias='City']}">
              <xsl:value-of select="data [@alias='City']" />
            </option>
          </xsl:for-each>
        </select>
    
      </xsl:template>
    
    But... still does not print Stockholm. C'mon XSLT-engine, this is not how I like to spend my time! :-o
  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 19:55
    Jonas Eriksson
    0

    This actually works (vb-code called from within xslt), if someone needs proof, I give you the login to my site:

        Public Function createListOfCities(ByVal nodeId As Integer) As String
    
            Dim myNode = New Node(nodeId)
            Dim resultHtml As New Text.StringBuilder
            If myNode.Children.Count > 0 Then
                resultHtml.Append("<ul>")
                Dim city As String = ""
    
                Dim listOfCities As New List(Of String)
                For Each childNode As Node In myNode.Children
                    city = childNode.GetProperty("City").Value
                    If Not (listOfCities.Contains(city)) Then l.Add(city)
                Next nn
    
                listOfCities.Sort()
                For Each sortedCity As String In listOfCities
                    resultHtml.Append("<li>")
                    resultHtml.Append(sortedCity)
                    resultHtml.Append("</li>")
                Next sortedCity
                resultHtml.Append("</ul>")
            End If
            Return resultHtml.ToString()
    
        End Function
    
    (I did a <ul> just for testing, should find a way for it to sort with swedish chars, then I'll make it a dropdown.)
  • Warren Buckley 2106 posts 4836 karma points MVP 7x admin c-trib
    Jan 20, 2010 @ 20:08
    Warren Buckley
    0

    Hi Jonas,
    Have you simplified your XSLT for debugging first?

    eg

    <xsl:for-each select="umbraco.library:GetXmlNodeById($companiesRoot)/node">

    Does the missing node now output, if so we can now identify that its this line that needs fixing.

    Warren

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 20:18
    Jonas Eriksson
    0

    Hi Warren! Thanks for being with me here. :-)

    I change to this:

    <xsl:for-each select="umbraco.library:GetXmlNodeById('6850')/node">
    <xsl:sort select="data [@alias='City']"/>
    <xsl:value-of select="data [@alias='City']"/>, 
    </xsl:for-each>

    And the output (some of it):

    Staffanstorp, Stenungsund, Stockholm, Stockholm, Stockholm, Stockholm, Stockholm, Stockholm, Stockholm, Stockholm, Stockholm, Stockholm, Stockholm, Stockholm, Stockholm, Stockholm, Stockholm, Strömstad, Sundsvall, Sundsvall, Sundsvall, Sundsvall, Sundsvall, Svenljun
  • Warren Buckley 2106 posts 4836 karma points MVP 7x admin c-trib
    Jan 20, 2010 @ 20:29
    Warren Buckley
    0

    OK so we definately know its something to do with that XSLT in the for-each then.

    I thought I had done some stuff with disctinct and XSLT, but I must have imagined it.
    However someone has a nice blog post that should help you to solve this.

    http://blackpoint.dk/umbraco-workbench.aspx?Snippet=/umbraco-workbench/xslt/grouping--distinct-values.aspx

    Warren

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 20:42
    Jonas Eriksson
    0

    Thanks, but that did not work either (!) 

      <xsl:key name="nodes-by-City" match="node" use="data [@alias='City']" />
      <xsl:template match="/">
    
        <select id="location" name="location">
          <option value="0">Choose location</option>
    
          <xsl:for-each select="umbraco.library:GetXmlNodeById(6850)/node[generate-id() = generate-id(key('nodes-by-City', data [@alias='City'])[1])]">
            <xsl:sort select="data [@alias='City']" lang="sv" />
            <option value="{data [@alias='City']}">
              <xsl:value-of select="data [@alias='City']" />
            </option>
          </xsl:for-each>
        </select>
    
      </xsl:template>
    
    I buy a license of Contour to the first one who solves this :-) For sure, I do! I'm not sure I can assist you with live testing very much though, let me get back on that if that's needed.
  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 20:44
    Jonas Eriksson
    0

    I'm off to sleep now. I would be the happiest umbracian if I got help with this during the night. See ya.

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 21:34
    Jonas Eriksson
    0

    I'm pretty sure some of you don't believe this error (?) :-o... I have a lot other stuff to finish, but I will keep you updated on this...

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Jan 20, 2010 @ 21:55
    Chriztian Steinmeier
    0

    Hi Jonas - I *do* believe you :-)

    Trying a couple of things... will return.

    /Chriztian

  • Thomas Höhler 1237 posts 1709 karma points MVP
    Jan 20, 2010 @ 22:05
    Thomas Höhler
    0

    Hi Jonas, I did set up a node with some subnodes with the property City. Then I tried you last code and it worked for me:

    The code:

    <xsl:key name="nodes-by-City" match="node" use="data [@alias='City']" />

    <xsl:template match="/">

       <select id="location" name="location">
          <option value="0">Choose location</option>

          <xsl:for-each select="umbraco.library:GetXmlNodeById(1966)/node[generate-id() = generate-id(key('nodes-by-City', data [@alias='City'])[1])]">
            <xsl:sort select="data [@alias='City']" lang="sv" />
            <option value="{data [@alias='City']}">
              <xsl:value-of select="data [@alias='City']" />
            </option>
          </xsl:for-each>
        </select>
      <hr />
      <ul>
        <xsl:for-each select="umbraco.library:GetXmlNodeById(1966)/node">
          <li><xsl:value-of select="@nodeName" /> - <xsl:value-of select="data[@alias='City']" /></li>
        </xsl:for-each>
      </ul>
    </xsl:template>

    the output: http://blog.thoehler.com/test/city-start

    So weird it is it works for me. Why not for you? btw: which umbraco version do you use on which Os do you work and which language settings do you have?

    Thomas

  • Peter Dijksterhuis 1442 posts 1722 karma points
    Jan 20, 2010 @ 22:10
    Peter Dijksterhuis
    0

    My 2 cents: names with special characters can have weird effect on some things. ë, ï, ö, etc.

    Try renaming cities that have a special char to the name without that char and see if that helps.

    Somehow the community will get this fixed ;-)

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 22:12
    Jonas Eriksson
    0

    Thanks guys, the best guess I have right now is that some odd char has gone into the field 'City' just for 'Stockholm' and breaks things (dunno how, but...) Also I haven't looked for all other cities, does seem complete though, should count them.

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Jan 20, 2010 @ 22:15
    Chriztian Steinmeier
    0

    Hi Jonas,

    All tests return the same here: Stockholm exists :-)

    I'm guessing there's a discrepancy between the published node tree and the tree you're getting from GetXmlNodeById()...

    /Chriztian

  • Thomas Höhler 1237 posts 1709 karma points MVP
    Jan 20, 2010 @ 22:18
    Thomas Höhler
    0

    agree, try to recycle the app pool to get the cache cleared. Also check the caching settings of the macro. I have tested the special characters in my solution and it had no probs...

    Thomas

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 22:19
    Jonas Eriksson
    0

    Ah, yes Peter, thanks, same thought. But how to do that quick n easy? With a function? There are some hundred companies in the list.

    And oh, Umbraco version is 4.0.3. Language settings, in umbraco? Swedish. In SQL SQL_Latin1_General_CP1_CI_AS. Server "Current format" English (United States) (That's what lang settings I can think of)

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 22:34
    Jonas Eriksson
    0

    Must be something strange with my node data, right? I'm struggling with this, but the xslt seem perfectly alright, doesn't it? So please, thanks for your help so far, no need to take your time more, if you don't want to ofcourse, the Contour-offer is still there, any suggestions of how to find out the erroneous node data (if thats what it is) or any other thougts are welcome! I'm of to bed now, have to sleep on this one.

  • Thomas Höhler 1237 posts 1709 karma points MVP
    Jan 20, 2010 @ 22:38
    Thomas Höhler
    0

    I think you are right. to solve this one may have access to the backend. If you want I have some minutes left...

    Thomas

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 23:14
    Jonas Eriksson
    0

    How to clean up messy nodes best?

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 20, 2010 @ 23:35
    Jonas Eriksson
    0

    I tried republish (on root companynode as well as content root). Also I made the app-pool recycle (by adding a space in web.config).

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 21, 2010 @ 14:26
    Jonas Eriksson
    0

    Thank you all, Warren, Criztian, Thomas & Peter. The actual error was in the xml somewhere, no one gave me the exact solution, but I like to give away my "price" anyway and I believe Criztians guess was the first on spot "I'm guessing there's a discrepancy between the published node tree and the tree you're getting from GetXmlNodeById()...". Ok Thomas? Also it was kind'a informative to use Criztians xmldump on the tree. 

    Oh, the solution : I copied the whole company tree to another so umbraco could recreate all nodes.

    Still one wonders why this happened. I did not inform you about the companies is imported from an external db. And first version of the import was not 100% bugfree whith publishing, so perhaps errors come from that.

    Criztians, please mejl me jonas programenta.se

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 21, 2010 @ 14:47
    Jonas Eriksson
    0

    A word about the "contest". It's not my intention to start some habit here. The forum is the best and a friendly and helpful one, without giveaways. I was quite desperate and really stuck. And very tired. And also I just started to play with Contour and thought is was a fun idea to buy a license for the one helps me out. Ok folks? :)

  • Thomas Höhler 1237 posts 1709 karma points MVP
    Jan 21, 2010 @ 15:21
    Thomas Höhler
    2

    Glad that it is solved.

    BTW: Some motivation is always good ;-), although the main motivation by the most of us is to help others to let the umbraco community be the best commnity ever. And for sure it is ok to give the 'price' ti Criztian, he had the right intention.

    The most important point is: this problem is solved...

    Cheers,
    Thomas

  • Jonas Eriksson 930 posts 1825 karma points
    Jan 21, 2010 @ 22:25
    Jonas Eriksson
    0

    Thank you Thomas :-)

    Just for the record, Contour is bought and delivered (well the license anyway). Have fun with Contour and good luck with that site Criztian!

    For all readers, this thread shows 4 ways of doing Select Disctinct, all work (right?), if the nodes are ok, not bad eh?

    Happy coding to all!

    /Jonas

Please Sign in or register to post replies

Write your reply to:

Draft