Copied to clipboard

Flag this post as spam?

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


  • mike_h 25 posts 49 karma points
    Nov 02, 2011 @ 10:43
    mike_h
    0

    Org Chart

    I've created an organisation tree representation in the content, so as an example I have nodes of:

    Group Compliance

    Head of Group Compliance

    Department 1

    Employee 1

    Employee 2

    Department 2

    Employee 1

    Department 3

     

    I need to get a nested XML output to feed into a organistion chart component, so this would look along the lines of:

    <item id="123" name="Head of Group Compliance">

    <item id="124" name="Department 1">

    <item id="125" name="Employee 1"></item>

    <item id="125" name="Employee 2"></item>

    </item>

    <item id="126" name="Department 2">

    <item id="127" name="Employee 1"></item>

    <item id="128" name="Employee 2"></item>

    </item>

    <item id="129" name="Department 3">

    </item>

    </item>
    I can't seem to get the nesting of the XML nodes to work correctly, Department 2 nests into Department 1 and Department 3 nests into Department 2 whereas they should be on the same level.
    This is the XSLT I'm using:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <xsl:stylesheet 
      version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      xmlns:msxml="urn:schemas-microsoft-com:xslt" 
      xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" 
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>

    <xsl:variable name="source" select="1372"/>    

    <xsl:template match="/">
      <xsl:call-template name="drawNodes">  
        <xsl:with-param name="parent" select="umbraco.library:GetXmlNodeById($source)/self::* [@isDoc]"/>  
      </xsl:call-template>
    </xsl:template>

    <xsl:template name="drawNodes">
      <xsl:param name="parent"/> 
      <xsl:for-each select="$parent/child::*[@isDoc and string(umbracoNaviHide) != '1']">
        <item id="{@id}" name="{@nodeName}">
          <xsl:if test="count($parent/child::* [@isDoc and string(umbracoNaviHide) != '1']) &gt; 0">   
            <xsl:call-template name="drawNodes">    
              <xsl:with-param name="parent" select="."/>    
            </xsl:call-template>  
          </xsl:if>
        </item>
      </xsl:for-each>
    </xsl:template>
        
        
    </xsl:stylesheet>
    Cheers,
    Mike


  • Rich Green 2246 posts 4008 karma points
    Nov 02, 2011 @ 10:49
    Rich Green
    0

    Hey Mike,

    Looks like you might have done so but the SiteMap.xslt that comes out the box with Umbraco should be able to achieve what you need without much tweaking?

    Rich

  • mike_h 25 posts 49 karma points
    Nov 02, 2011 @ 11:05
    mike_h
    0

    Hi Rich,

    Yes the xslt is based on the SiteMap and if I was using the 'ul' and 'li' tags it looks OK, however if I ditch the 'ul' tags and swap out the 'li' tags for the xml 'item' tags then the nesting is not correct ?

    Cheers,

     

    Mike

     

     

  • Rich Green 2246 posts 4008 karma points
    Nov 02, 2011 @ 11:16
    Rich Green
    0

    Hey Mike,

    Can you post a pic of your Content Tree and also the html produced (or maybe the a snippet)?

    Rich

  • mike_h 25 posts 49 karma points
    Nov 02, 2011 @ 12:10
    mike_h
    0

    Hi Rich,

    Thanks for yur help, the node structure is as described in my original post, here's a sample of the XML output:

    <?xml version="1.0" encoding="UTF-8"?>
    <item id="" name="Head of Group Compliance">
      <item id="" name="Department 1">
        <item id="" name="Employee 1">
          <item id="" name="Employee 2"></item>
          <item id="" name="Department 2">
            <item id="" name="Employee 1">
              <item id="" name="Employee 2"></item>
              <item id="" name="Department 3"></item>
              <item id="" name="Department 1">
                <item id="" name="Employee 1">
                  <item id="" name="Employee 2"></item>
                  <item id="" name="Employee 1">
                    <item id="" name="Employee 2">
                      <item id="" name="Department 2">
                        <item id="" name="Employee 1">
                          <item id="" name="Employee 2"></item>
                          <item id="" name="Employee 1">
                            <item id="" name="Employee 2">
                              <item id="" name="Department 3"></item>
                            </item>
                          </item>
                        </item>
                      </item>
                    </item>
                  </item>
                </item>
              </item>
            </item>
          </item>
        </item>
      </item>
    </item>  

    Mike

  • Rich Green 2246 posts 4008 karma points
    Nov 02, 2011 @ 12:42
    Rich Green
    0

    Hey Mike,

    I'm not sure why you've made the changes that you have from the original site map xslt?

    I'm guessin its this line that's causing the problem

     <xsl:for-each select="$parent/child::*[@isDoc and string(umbracoNaviHide) != '1']">

     

    What does this get you?

    <!-- update this variable on how deep your site map should be -->
    <xsl:variable name="maxLevelForSitemap" select="4"/>
     
    <xsl:template match="/">
    <div id="sitemap"> 
    <xsl:call-template name="drawNodes">  
    <xsl:with-param name="parent" select="umbraco.library:GetXmlNodeById(1372)"/>  
    </xsl:call-template>
    </div>
    </xsl:template>
     
    <xsl:template name="drawNodes">
    <xsl:param name="parent"/> 
    <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1 and umbraco.library:IsLoggedOn() = 1)">
    <ul><xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]"> 
    <li>  
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/></a>  
    <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]) &gt; 0">   
    <xsl:call-template name="drawNodes">    
    <xsl:with-param name="parent" select="."/>    
    </xsl:call-template>  
    </xsl:if> 
    </li>
    </xsl:for-each>
    </ul>
    </xsl:if>
    </xsl:template>

    Rich

  • mike_h 25 posts 49 karma points
    Nov 02, 2011 @ 13:05
    mike_h
    0

    Hi Rich,

    I've just tried that but it still nests the departments


    <item id="1399" name="Head of Group Compliance">
      <item id="1400" name="Department 1">
        <item id="1403" name="Employee 1">
          <item id="1404" name="Employee 2">item>
          <item id="1401" name="Department 2">
            <item id="1405" name="Employee 1">
              <item id="1406" name="Employee 2">item>
              <item id="1402" name="Department 3">item>
            item>
          item>
        item>
      item>
    item>

     

    Here's a screen grab of the node structure:

     

    Cheers,

     

    Mike

     

  • Rich Green 2246 posts 4008 karma points
    Nov 02, 2011 @ 13:10
    Rich Green
    0

    Hey Mike,

    Very strange indeed.

    However that cannot be the output from the code I posted as my posted code was writing out anchor links.

    Would be good to see your content tree as well (I know you say it's structured as in post 1 but would be good incase something else is going on)

    Rich

  • Rich Green 2246 posts 4008 karma points
    Nov 02, 2011 @ 13:12
    Rich Green
    0

    Sorry, cross post, I couldn't see your content structure before!

    Still be interested to see the actual output of my code posted above.

    We'll get there!

    Rich

  • mike_h 25 posts 49 karma points
    Nov 02, 2011 @ 13:27
    mike_h
    0
  • Rich Green 2246 posts 4008 karma points
    Nov 02, 2011 @ 13:30
    Rich Green
    0

    Hey Mike,

    That looks like what you need right, departments and Employees all look correct.

    So you just need to edit this xslt to produce your xml (unless I'm mistaken)

    Rich

     

  • mike_h 25 posts 49 karma points
    Nov 02, 2011 @ 13:44
    mike_h
    0

    Hi Rich,

    I've modified the xslt as follows, and included the output below it.

      <!-- update this variable on how deep your site map should be -->
      <xsl:variable name="maxLevelForSitemap" select="6"/>
       
      <xsl:template match="/">
        <div id="sitemap"
          <xsl:call-template name="drawNodes">  
            <xsl:with-param name="parent" select="umbraco.library:GetXmlNodeById(1398)"/>  
          </xsl:call-template>
        </div>
      </xsl:template>
       
      <xsl:template name="drawNodes">
        <xsl:param name="parent"/> 
        <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1 and umbraco.library:IsLoggedOn() = 1)">
          <item id="{@id}" name="{@nodeName}">
          <xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]"
            <item id="{@id}" name="{@nodeName}">  
            <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]) &gt; 0">   
              <xsl:call-template name="drawNodes">    
                <xsl:with-param name="parent" select="."/>    
              </xsl:call-template>  
            </xsl:if
            </item>
          </xsl:for-each>
          </item>
        </xsl:if>
      </xsl:template>

     

    Output:

    <?xml version="1.0" encoding="UTF-8"?>
    <div id="sitemap">
      <item id="" name="">
        <item id="1399" name="Head of Group Compliance">
          <item id="1399" name="Head of Group Compliance">
            <item id="1400" name="Department 1">
              <item id="1400" name="Department 1">
                <item id="1403" name="Employee 1">
                  <item id="1404" name="Employee 2"></item>
                </item>
                <item id="1401" name="Department 2">
                  <item id="1401" name="Department 2">
                    <item id="1405" name="Employee 1">
                      <item id="1406" name="Employee 2"></item>
                    </item>
                    <item id="1402" name="Department 3"></item>
                  </item>
                </item>
              </item>
            </item>
          </item>
        </item>
      </item>
    </div>    

     

    Cheers,

    Mike

     

  • Rich Green 2246 posts 4008 karma points
    Nov 02, 2011 @ 13:47
    Rich Green
    0

    Hey Mike,

    Your code has an error as you've added an another item within the loop.

     

    Try this

    <!-- update this variable on how deep your site map should be -->
    <xsl:variable name="maxLevelForSitemap" select="4"/>
     
    <xsl:template match="/">
    <div id="sitemap"> 
    <xsl:call-template name="drawNodes">  
    <xsl:with-param name="parent" select="umbraco.library:GetXmlNodeById(1372)"/>  
    </xsl:call-template>
    </div>
    </xsl:template>
     
    <xsl:template name="drawNodes">
    <xsl:param name="parent"/> 
    <xsl:if test="umbraco.library:IsProtected($parent/@id, $parent/@path) = 0 or (umbraco.library:IsProtected($parent/@id, $parent/@path) = 1 and umbraco.library:IsLoggedOn() = 1)">
    <xsl:for-each select="$parent/* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]"> 
    <item>  
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/></a>  
    <xsl:if test="count(./* [@isDoc and string(umbracoNaviHide) != '1' and @level &lt;= $maxLevelForSitemap]) &gt; 0">   
    <xsl:call-template name="drawNodes">    
    <xsl:with-param name="parent" select="."/>    
    </xsl:call-template>  
    </xsl:if> 
    </item>
    </xsl:for-each>
     
    </xsl:if>
    </xsl:template>
     
    Rich

  • mike_h 25 posts 49 karma points
    Nov 02, 2011 @ 13:53
    mike_h
    0

    Hi Rich,

    This is the output I get using your modified xslt:

    <?xml version="1.0" encoding="UTF-8"?>
    <div id="sitemap">
      <item id="1399" name="Head of Group Compliance">
        <item id="1400" name="Department 1">
          <item id="1403" name="Employee 1">
            <item id="1404" name="Employee 2"></item>
            <item id="1401" name="Department 2">
              <item id="1405" name="Employee 1">
                <item id="1406" name="Employee 2"></item>
                <item id="1402" name="Department 3"></item>
              </item>
            </item>
          </item>
        </item>
      </item>
    </div>    

    Cheers,

     

    Mike

     

  • mike_h 25 posts 49 karma points
    Nov 02, 2011 @ 15:30
    mike_h
    0

    Hi Rich,

    Thanks very much for your help, I managed to get to the bottom of it, as you've indicated and I had thought all along it looks like it should work, eventually figured out that you need to change the xsl output method to 'html' instead of the default 'xml', not sure why that makes it work though, hopefully someone can explain.

    Default is:

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    Changed to:

    <xsl:output method="html" omit-xml-declaration="yes"/>

    Cheers,

     

    Mike

     

  • Rich Green 2246 posts 4008 karma points
    Nov 02, 2011 @ 15:31
    Rich Green
    0

    Hey Mike,

    Glad you got it sorted :)

    Rich

  • Sekou Terry 4 posts 71 karma points
    Mar 14, 2013 @ 19:21
    Sekou Terry
    0

    This thread is years old, but if anyone else comes across this post I ran into a similar problem and produced the same kind of erroneous code as shown above. My problem was (and it might be here too) that the xPath in my select statement didn't give me access to the nodes I wanted it to because I wasn't looking for them in the right level of hierarchy. Take a look at your for-each statement:

    <xsl:for-each select="$parent/child::*[@isDoc and string(umbracoNaviHide) != '1']">

    You may need to change that xPath to get to your nodes. Hope this helps someone.

Please Sign in or register to post replies

Write your reply to:

Draft