Solved

XSLT Sarissa XML

Posted on 2011-09-13
6
428 Views
Last Modified: 2012-05-12
Hi,

I have some XML. I am trying to create a structure that works in much the same way as Windows Explorer. My XSL seems to break down here, on my for loop, which I basically cut and paste from another source.

<xsl:for-each select="key('obj', $detail-id)/*[not(self::name)]">        

I was hoping someone would know how I can get it too render properly. So that I can click on an item and it goes into the next level displaying all of these items. I am using sarissa, I can gladly provide the .js though I think it is problem with this loop structure where the problem exists.

NOTE- The below code is only done for type 'folder', it is intended for type folder and file, both of which can be placed at any level, and can have each other inside each other.

Thanks in advance.
Here is xml example:

<?xml version="1.0" encoding="utf-8"?>
<testData>
  <items id="0">
    <item id="1" name="Item1" type="file">
      <item id="4" name="Item4" type="folder">
        <item id="5" name="Item5" type="file"/>
        <item id="6" name="Item6" type="folder" />
      </item>
      <item id="2" name="Item2" type="folder" />
        <item id="3" name="Item3" type="folder"  />
      </item>
   </items>
</testData>

Here is xsl structure:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:key name="obj" match="*" use="@id"/>
  <xsl:param name="detail-id">sms</xsl:param>
  <xsl:template match="testData">
  <xsl:apply-templates />
  </xsl:template>
<xsl:template match="item/*">
      <xsl:for-each select="key('obj', $detail-id)/*[not(self::name)]">  
        <xsl:choose>
          <xsl:when test="@type = 'folder'">
            <span id="{@id}" >
              <xsl:attribute name="onclick">
                <xsl:text>DisplayResult('</xsl:text>
                <xsl:value-of select="@id"/>
                <xsl:text>','</xsl:text>
                <xsl:value-of select="name()"/>
                <xsl:text>');</xsl:text>
              </xsl:attribute>
              <xsl:value-of select="@name"></xsl:value-of>
            </span>
          </xsl:when>
        </xsl:choose>        
      </xsl:for-each>
  </xsl:template>
  </xsl:stylesheet>

Open in new window

0
Comment
Question by:metta0_3
  • 3
  • 3
6 Comments
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 36530047
If this is XSLT for Sarissa, it is bound to break,
Sarissa requires wellformed XML as a transform result... meaning one single root

further more, it is not very clear what you need.
Do you want to expand one further level given the id?
that the following is about what you need

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:key name="obj" match="*" use="@id"/>
    <xsl:param name="detail-id">1</xsl:param>
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="testData">
        <!-- relies on teh key only returning one object -->
        <xsl:apply-templates select="key('obj', $detail-id)"/>
    </xsl:template>
    <xsl:template match="item"><!-- actually only the keyed one -->
        <div><!-- creating a container for Sarissa -->
            <xsl:copy-of select="@id | @name"/> <!-- at least copying the id for later overwrite -->
            <xsl:for-each select="*">
                <xsl:if test="@type = 'folder'">
                    <span id="{@id}" >
                        <xsl:attribute name="onclick">
                            <xsl:text>DisplayResult('</xsl:text>
                            <xsl:value-of select="@id"/>
                            <xsl:text>','</xsl:text>
                            <xsl:value-of select="name()"/>
                            <xsl:text>');</xsl:text>
                        </xsl:attribute>
                        <xsl:value-of select="@name"></xsl:value-of>
                    </span>
                </xsl:if>
            </xsl:for-each>        
        </div>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 36530055
now you need a smart override, by letting the XSL result override the outer html of the identified div
that is how you can close the stuff back if you want later
0
 

Author Comment

by:metta0_3
ID: 36530220
What you have provided is pretty close. Thanks. detail-id set to 1 is causing an issue for me. Its for a search filter, so a user might decide to start the search from another item within the tree. The xml is actually the result based on what is sent to the server by the user.

<xsl:param name="detail-id">1</xsl:param>

Open in new window


For example the result might be further in the tree like this

<?xml version="1.0" encoding="utf-8"?>
<testData>
  <items id="0">
      <item id="4" name="Item4" type="folder">
        <item id="5" name="Item5" type="file"/>
        <item id="6" name="Item6" type="folder" />
      </item>
      <item id="2" name="Item2" type="folder" />
        <item id="3" name="Item3" type="folder"  />
      </item>
</testData>

Open in new window


Therefore item 4 and 2 are the first to be displayed. Also it is unlimited the levels that I wish to be able to click through.

0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 

Author Comment

by:metta0_3
ID: 36530268
Ok this seems to work as I always have the root element id=0. I think I am there.
<xsl:param name="detail-id">1</xsl:param>

Open in new window


Athough can I do this, just to save code.

<xsl:if test="@type = 'folder'" | "@type='file'>

Open in new window

0
 

Author Comment

by:metta0_3
ID: 36530296
The above comment was meant to say this.

<xsl:param name="detail-id">1</xsl:param>

Open in new window


Now I just want to shorten the below as I am producing unnecessary code.

<xsl:for-each select="*">
          <xsl:if test="@type = 'folder'">
            <span id="{@id}" >
              <xsl:attribute name="onclick">
                <xsl:text>DisplayOverview('</xsl:text>
                <xsl:value-of select="@id"/>
                <xsl:text>','</xsl:text>
                <xsl:value-of select="name()"/>
                <xsl:text>');</xsl:text>
              </xsl:attribute>
              <xsl:value-of select="@name"></xsl:value-of>
            </span>
          </xsl:if>
          <xsl:if test="@type = 'file'">
            <span id="{@id}" >
              <xsl:attribute name="onclick">
                <xsl:text>DisplayOverview('</xsl:text>
                <xsl:value-of select="@id"/>
                <xsl:text>','</xsl:text>
                <xsl:value-of select="name()"/>
                <xsl:text>');</xsl:text>
              </xsl:attribute>
              <xsl:value-of select="@name"></xsl:value-of>
            </span>
          </xsl:if>
        </xsl:for-each>

Open in new window

0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 36532186
Hi,

was gone for a while, seems you fixed it by now

<xsl:if test="@type = 'folder'" | "@type='file'>

should be

<xsl:if test="@type = 'folder'" or "@type='file'>
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
tutorial for ebay api 3 32
PHP Installer 5 19
XML Document XPath with Namespaces 3 20
why $(this).attr('id'); function not returning value ? 9 32
"In order to have an organized way for empathy mapping, we rely on a psychological model and trying to model it in a simple way, so we will split the board to three section for each persona and a scenario and try to see what those personas would Do,…
Because your company can’t afford for you to make SEO mistakes, you’ll want to ensure you’re taking the right steps each and every time you post a new piece of content. This list of optimization do’s and don’ts can help you become an SEO wizard.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Any person in technology especially those working for big companies should at least know about the basics of web accessibility. Believe it or not there are even laws in place that require businesses to provide such means for the disabled and aging p…

776 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