Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XSLT to show detail from a selected list?

Status
Not open for further replies.

jeffward

MIS
Jul 3, 2002
33
GB
Hi im fairly new to XML but I trying to generate documentation for a number of programs that have been saved as XML files (I have no control over the content of the source XML file).

A simplification of one of these files would be something like this: -

<Form name="form1" description="this is a test form">
<Screen name="screen1" description="this is screen1">
<Button name="button1" description="this is button1" prop1="blah" property2="blah" prop3="blah" etc>
</Button>
<Button name="button2" description="this is button2" prop1="blah" property2="blah" prop3="blah" etc>
</Button>
</Screen>
<Screen name="screen2" description="this is screen2">
<Button name="button1" description="this is button1" prop1="blah" property2="blah" prop3="blah" etc>
</Button>
<Button name="button2" description="this is button2 "prop1="blah" property2="blah" prop3="blah" etc>
</Button>
</Screen>
</Form>

This is a very simplified example but shows that there cane be nodes with the same name i.e. Button1 and that there is no clear way to identify which Button1 node we are interested in without looking at the full path.

I have worked out how to use XSLT to produce a collabsible list from this XML that looks something like this:-

-Form1
-Screens
-Screen1
-Buttons
-Button1
-Button2
-Screen2
-Buttons
-Button1
-Button2

What i now need to do is show the detail from the selected object, for example if the user clicks on Button1 under Screen1 then I would like a detail frame to show something like: -

Form1/Screen1/Button1
This is button 1

Properties:
Blah
Blah
Blah
 
How about this (didn't make the list collapsable):
Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
  <xsl:template match="node()">
    <li>
      <a>
        <xsl:attribute name="href">javascript: open_win('<xsl:call-template name="details"><xsl:with-param name="node" select="."/></xsl:call-template>')</xsl:attribute>
        <xsl:value-of select="@name"/>
      </a>
      <xsl:if test="*">
        <ul>
          <xsl:apply-templates select="node()"/>
        </ul>
      </xsl:if>
    </li>
  </xsl:template>
  <xsl:template match="Form">
    <html>
      <head>
        <title>Test</title>
        <script type="text/javascript">
function open_win(str) 
{
  var win = window.open('', '_blank', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=400, height=400');
  win.document.write(str);
}
        </script>
      </head>
      <body>
        <ul>
          <li>
            <a>
              <xsl:attribute name="href">javascript: open_win('<xsl:call-template name="details"><xsl:with-param name="node" select="."/></xsl:call-template>')</xsl:attribute>
              <xsl:value-of select="@name"/>
            </a>
            <ul>
              <xsl:apply-templates/>
            </ul>
          </li>
        </ul>
      </body>
    </html>
  </xsl:template>
  <xsl:template name="details">
    <xsl:param name="node"/>
    <![CDATA[<html><head><title>Details</title></head><body><p>]]>
    <xsl:call-template name="path">
      <xsl:with-param name="node" select="."/>
    </xsl:call-template>
    <![CDATA[</p><p>]]>
    <xsl:value-of select="$node/@description"/>
    <![CDATA[</p><p>Properties:</p><ul>]]>
    <xsl:for-each select="$node/@*[position() &gt; 2]">
      <xsl:text>&lt;li&gt;</xsl:text>
      <xsl:value-of select="concat(name($node), ': ')"/>
      <xsl:value-of select="."/>
      <xsl:text>&lt;/li&gt;</xsl:text>
    </xsl:for-each>
    <![CDATA[</ul></p></body></html>]]>
  </xsl:template>
  <xsl:template name="path">
    <xsl:param name="node"/>
    <xsl:if test="$node/../..">
      <xsl:call-template name="path">
        <xsl:with-param name="node" select="$node/.."/>
      </xsl:call-template>
      <xsl:text>/</xsl:text>
    </xsl:if>
    <xsl:value-of select="$node/@name"/>
  </xsl:template>
</xsl:stylesheet>

Jon

"There are 10 types of people in the world... those who understand binary and those who don't.
 
Thanks Jon

Thats more or less what I was looking for except i wanted the detail displayed in the same window but i can probably work out how to do this.

I had managed to come up with a solution that works using generate-id but still hadnt worked out how to show the full path, also your code is a lot shorter ;) so thanks for the quick response
 
Slightly neater version that displays details in same window:
Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
  <xsl:template match="node()">
    <li>
      <a>
        <xsl:attribute name="href"><xsl:call-template name="details"><xsl:with-param name="node" select="."/></xsl:call-template></xsl:attribute>
        <xsl:value-of select="@name"/>
      </a>
      <xsl:if test="*">
        <ul>
          <xsl:apply-templates select="node()"/>
        </ul>
      </xsl:if>
    </li>
  </xsl:template>
  <xsl:template match="Form">
    <html>
      <head>
        <title>Test</title>
        <script type="text/javascript">
<![CDATA[
function changeDetails(path, desc, props) 
{
  document.getElementById('details').style.display = "block";
  document.getElementById('path').innerHTML = path;
  document.getElementById('desc').innerHTML = desc;
  var proplist = document.getElementById('props');
  while(proplist.childNodes.length > 0)
  {
    proplist.removeChild(proplist.firstChild);
  }
  if (props.length > 0)
  {
    for(var i = 0; i < props.length; i++)
    {
      var li = document.createElement('li');
      li.innerHTML = props[i];
      proplist.appendChild(li);
    }
  }
  else
  {
    var li = document.createElement('li');
    li.innerHTML = "None";
    proplist.appendChild(li);
  }
}
]]>
        </script>
      </head>
      <body>
        <ul id="Elements" style="float: left; margin: 10px;">
          <li>
            <a>
              <xsl:attribute name="href"><xsl:call-template name="details"><xsl:with-param name="node" select="."/></xsl:call-template></xsl:attribute>
              <xsl:value-of select="@name"/>
            </a>
            <ul>
              <xsl:apply-templates/>
            </ul>
          </li>
        </ul>
        <div id="details" style="float: left; display: none; width: 200px; border: 1px dashed black; padding: 5px;">
          <p id="path" style="font-weight: bold;">None selected</p>
          <p id="desc">N/A</p>
          <p>Properties:</p>
          <ul id="props">
            <li>None</li>
          </ul>
        </div>
      </body>
    </html>
  </xsl:template>
  <xsl:template name="details">
    <xsl:param name="node"/>
    <xsl:text>javascript: changeDetails('</xsl:text>
    <xsl:call-template name="path">
      <xsl:with-param name="node" select="."/>
    </xsl:call-template>
    <xsl:text>', '</xsl:text>
    <xsl:value-of select="$node/@description"/>
    <xsl:text>', [</xsl:text>
    <xsl:for-each select="$node/@*[position() &gt; 2]">
      <xsl:text>'</xsl:text>
      <xsl:value-of select="concat(name($node), ': ')"/>
      <xsl:value-of select="."/>
      <xsl:choose>
        <xsl:when test="position() + 2 &lt; count($node/@*)">
          <xsl:text>', </xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>'</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
    <xsl:text>]);</xsl:text>
  </xsl:template>
  <xsl:template name="path">
    <xsl:param name="node"/>
    <xsl:if test="$node/../..">
      <xsl:call-template name="path">
        <xsl:with-param name="node" select="$node/.."/>
      </xsl:call-template>
      <xsl:text>/</xsl:text>
    </xsl:if>
    <xsl:value-of select="$node/@name"/>
  </xsl:template>
</xsl:stylesheet>

Jon

"There are 10 types of people in the world... those who understand binary and those who don't.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top