Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old July 30th, 2009, 01:17 PM
Registered User
 
Join Date: Jul 2009
Posts: 6
Thanks: 2
Thanked 0 Times in 0 Posts
Default Convert substring to node set in XSLT 1.0

Hello,

I'm using Interwoven's TeamSite 6.7.2 to create new Web pages. TS672 uses XSLT 1.0 and Xalan as its processor. This is what I'm trying to do:

I have a number of articles, and some contain references to other snippets of content. This is an example of the native XML from one of data capture templates (forms) that we use:

Code:
<Properties ComponentID="1228170816873" Admin="true">
  <Data>
    <Datum ID="D01" Type="DCR" Name="My DCR">
      <DCR Category="WebKBdocs" Type="KBdoc">
        <record name="product\ESR10603" type="content">
	<item name="DocType">
	  <value>KBDOC</value> 
	</item>
	<item name="DocID">
	  <value>ESR10603</value> 
	</item>
	<item name="Title">
	  <value>Translating Files</value> 
	</item>
	<item name="ContentArea">
	  <value>
	    <item name="Condition" /> 
	      <item name="DPList">
	        <value>
	          <item name="DPItem">
                         <value>NODECISIONPOINT</value> 
	          </item>
	          <item name="DPValue">
                         <value>yes</value> 
	          </item>
	        </value>
                   </item>
                   <item name="ContentSubSection">
	        <value>
		<item name="ContentType">
		  <value>general</value> 
		</item>
		<item name="Customers">
		  <value>ALL</value> 
		</item>
		<item name="ContentSection">
		  <value><p>Sample article content.</p> <p><snippet class="sniplink" name="SNIP/product/ESRx10094" dcrpath="/default/main/Company/Enterprise/Industry/MainframeSW/WORKAREA/KBContent/templatedata/WebKBdocs/ContentSnippet/data/product/ESRx10094" htmlpath="Y:/default/main/Company/Enterprise/Industry/MainframeSW/WORKAREA/KBContent/preview_files/SNIP/product/ESRx10094.html">Snippet Link ESRx10094</snippet></p>  <p><snippet class="sniplink" name="SNIP/product/ESRx10107" dcrpath="/default/main/Company/Enterprise/Industry/MainframeSW/WORKAREA/KBContent/templatedata/WebKBdocs/ContentSnippet/data/product/ESRx10107" htmlpath="Y:/default/main/Company/Enterprise/Industry/MainframeSW/WORKAREA/KBContent/preview_files/SNIP/product/ESRx10107.html">Snippet Link ESRx10107</snippet></p>
		  </value> 
                         </item>
	        </value>  
                   </item>
	  </value>
	</item>
        </record>
      </DCR>
    </Datum>
  </Data>
</Properties>
Outside of TeamSite, I can use a variable to access the @dcrpath value and then pass it to the document function, and my single-sourced content snippet appears in the article (it doesn't necessarily appear in place of the Snippet Link reference in the ContentSection since I can't use replace() in XSLT1.0, but I'm taking baby steps as I write the stylesheet - right now I just want to access the dcrpath attribute).

This is my XSL that works outside of TeamSite:

Code:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
  <head>
    <meta http-equiv="author" content="Jessica DEustachio" />
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <meta http-equiv="content-type" content="text/xml;charset=utf-8" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <link rel="stylesheet" type="text/css" href="../theme/kbcontent.css" />
  </head>
	  
  <body>
    <p class="pagetitle"><xsl:value-of disable-output-escaping="yes" select="/Properties/Data/Datum[@ID='D01']/DCR[@Type='KBdoc']/record/item[@name='Title']/value" /> </p>
    <p class="superviewer"><b>SME Information: </b><br />
      Doctype: <xsl:value-of disable-output-escaping="yes" select="/Properties/Data/Datum[@ID='D01']/DCR[@Type='KBdoc']/record/item[@name='DocType']/value" /> --
			DocID: <xsl:value-of disable-output-escaping="yes" select="/Properties/Data/Datum[@ID='D01']/DCR[@Type='KBdoc']/record/item[@name='DocID']/value" /> --
      </p>
      <hr />
      <xsl:apply-templates select="/Properties/Data/Datum[@ID='D01']/DCR[@Type='KBdoc']/record/item[@name='ContentArea']/value" />
      <hr />
  </body>
</html>
</xsl:template>

<xsl:template match="/Properties/Data/Datum[@ID='D01']/DCR[@Type='KBdoc']/record/item[@name='ContentArea']/value">

  <p class="superviewer"><b>Content Area <xsl:value-of select="count(preceding-sibling::value) + 1"/></b></p>

  <xsl:for-each select="item[@name='ContentSubSection']/value">
    <xsl:value-of disable-output-escaping="yes" select="item[@name='ContentSection']/value"/>	   
    <br/> 

    <xsl:variable name="snippetpath">
      <xsl:choose>
        <xsl:when test="contains(item[@name='ContentSection']/value,'Snippet')" >	
	<xsl:value-of select="item[@name='ContentSection']/value/p/snippet/@dcrpath"/>	
        </xsl:when>
      </xsl:choose>
    </xsl:variable>

    <xsl:choose>
      <xsl:when test="contains(item[@name='ContentSection']/value,'Snippet')" >		 
        <p>		
	<xsl:copy-of select="document($snippetpath)//Properties/Data/Datum[@ID='D02']/DCR[@Type='ContentSnippet']/record/item[@name='ContentArea']/value/item[@name='ContentSubSection']/value/item[@name='ContentSection']/value"/>
        </p>				
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="item[@name='ContentSection']/value"/>	
	<br/>  
        </xsl:otherwise>
      </xsl:choose>	
  </xsl:for-each>		
</xsl:template>



  <!-- Copy HTML to output without modification -->

  <xsl:template match="text()|@*|*">
    <xsl:copy>
      <xsl:apply-templates select="*|@*|text()"/>
	  <!--<xsl:value-of disable-output-escaping="yes" select="."/>-->
    </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>

When I place a copy of the stylesheet into the TeamSite component for the Web page, it doesn't process the variable. Specifically, everything after Properties/Data/Datum/DCR/record/item[name='ContentArea']/value/item[name='ContentSubSection']/value/item[name='ContentSection']/value is processed as a substring, so I can't get to the @dcrpath unless I convert it to a node set.

I've tried using xalan:nodeset, and it doesn't seem to work. This is what I did to use it, and I'm not sure if I'm using it correctly:

Code:
<xsl:variable name="vfecontent">
  <xsl:value-of select="item[@name='ContentSection']/value"/>
</xsl:variable>

<xsl:copy>
  <xsl:copy-of select="xalan:nodeset($vfecontent)/p/snippet/@dcrpath" />
</xsl:copy>
Given the limitations and the fact that TeamSite sees the content as a substring, does anyone know how I can get the @dcrpath value and pass it to the document function? Once I have it, does anyone have any suggestions on how to replace the Snippet Link reference with the snippet content?

Many thanks in advance.
 
Old July 30th, 2009, 01:44 PM
Friend of Wrox
 
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
Default

I am afraid I am lost in all those stuff you posted, you might want to try to reduce XML and XSLT to a minimum to demonstrate the problem you face.
What I can tell you is that the nodeset extension function is used to convert a result tree fragment into a node-set: http://xml.apache.org/xalan-j/extens...tml#ex-nodeset. If you have a string with an XPath expression and want to evaluate that then you need http://xml.apache.org/xalan-j/extens....html#evaluate.
I am however not sure whether you need one or the other at all, you seem to have neither a result tree fragment nor an XPath expression but rather a string with markup you want to parse. Whether Xalan has an extension for that I do not know.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
 
Old July 30th, 2009, 02:21 PM
Registered User
 
Join Date: Jul 2009
Posts: 6
Thanks: 2
Thanked 0 Times in 0 Posts
Default

Sorry about that. Here's a simplified version. This is my article XML:

Code:
<?xml version="1.0" ?> 
<?xml-stylesheet type="text/xsl" href="sample.xsl"?>

<article>
  <item name="ContentSection">
    <value>
	  <p>Sample article content.</p> 
	  <p><snippet class="sniplink" 
	  	name="SNIP/product/ESRx10094" 
	  	dcrpath="product/ESRx10094" 
	  	htmlpath="Y:/product/ESRx10094.html">
	  	Snippet Link ESRx10094
	     </snippet>
	  </p> 
    </value>   
  </item>
</article>
This is the content snippet I'm trying to include using the dcrpath attribute from above:

Code:
<?xml version="1.0" ?>

<item name="ContentSection">
  <value>
    <p>Text files have plain text. That is, text without formatting. The files have no special fonts, hyperlinks, or images.</p> 
    <p>In text files, data is split by delimiters; characters that separate each field of text. Here are some types of text files and their delimiters.</p> 
    <blockquote>
    <table cellspacing="1" cellpadding="3" width="80%" border="1"> <tbody> <tr> <td class="Table_head_left" width="25%">If the file<br /> extension is . . . </td> <td class="Table_head_left" valign="bottom">It is a . . . </td> </tr> <tr bgcolor="#f1f7f0"> <td>.txt</td> <td>Tab delimited file. Usually, a tab separates each column.</td> </tr> <tr bgcolor="#dbe9da"> <td>.csv</td> <td>Comma separated value file. Usually, a comma (,) separates each column.</td> </tr> <tr bgcolor="#f1f7f0"> <td>.prn</td> <td>Fixed-length or space delimited file. Usually, several spaces separate each column.</td> </tr> </tbody> 
    </table> 
    </blockquote> 
    <p>This is what data would look like for each file type, respectively:</p> 
  </value> 
</item>
This is the XSL file that works outside of TeamSite:

Code:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <xsl:apply-templates select="article/item/value" />
</xsl:template>

<xsl:template match="article/item/value">

  <xsl:variable name="snippetpath">
        <xsl:value-of select="p/snippet/@dcrpath"/>	
  </xsl:variable>
  
  <xsl:choose>
    <xsl:when test="contains(current(),'Snippet')" >		 
      <p>		
      <xsl:copy-of select="document($snippetpath)//item/value"/>
      </p>				
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy-of select="."/>	
	  <br/>  
    </xsl:otherwise>
  </xsl:choose>	
  
</xsl:template>
  
</xsl:stylesheet>
When this is put into TeamSite, the snippetpath variable is not recognized because TeamSite sees everything between the value tags in my article XML as a substring, not as a node set. You are correct in assuming I want to parse that substring, but netither XPath evaluate nor Node-Set will work. I'm afraid I'm stuck with the substring...
 
Old July 30th, 2009, 02:51 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

I've no idea what TeamSite is, but I think you've misdiagnosed the problem. I think it's simply a question of calling document() with a relative URI that is resolved against the wrong base URI. Start by changing this:

Code:
  <xsl:variable name="snippetpath">
        <xsl:value-of select="p/snippet/@dcrpath"/>    
  </xsl:variable>
to this:

Code:
  <xsl:variable name="snippetpath" select="p/snippet/@dcrpath"/>
This is always good practice anyway (your code will be shorter, more readable, and probably much faster). But this is also an example of where the second form is correct and the first one is wrong: that's because calling the document() function with a node as the argument, rather than a result tree fragment, invokes different rules for resolving a relative URI. When you pass a node, the URI is resolved against the base URI of that node, that is, the base URI of the document containing the snippet.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference





Similar Threads
Thread Thread Starter Forum Replies Last Post
convert nodeset to a single node newbies1234 XSLT 2 August 18th, 2008 10:01 AM
XPath: set operation with a disjoint node set rich_unger XSLT 7 May 6th, 2008 09:24 AM
Convert attribute to node-set using xalan Coolcampers XSLT 1 May 3rd, 2008 06:06 AM
Filtering out from a node set anothervbaddict XSLT 1 May 22nd, 2007 08:42 AM
node-set function Bernardo Pacheco XSLT 2 June 19th, 2006 10:45 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.