Hi Michael,
We are finally seeing the light at the end of this tunnel. I managed to extract every element values in <p> (single/multiples) except one with the following structure:
<p>
<strong>Hobbies:</strong>
<a shape="rect" href="http://www.hobbies.com/fishing" title="Shark Hunting">Coral Bay</a>
fishing
</p>
I tried the following combinations to get the value 'fishing' without much luck:
<xsl:template match="ns:p[ns:strong='Hobbies:']">
<xsl:for-each select="text()[normalize-space() != '']">
<hobbies><xsl:value-of select="normalize-space()"/></hobbies>
</xsl:for-each>
</xsl:template>
or
<xsl:template match="ns:p[ns:strong='Hobbies:']">
<xsl:for-each select="../ns:a/text()[normalize-space() != '']">
<hobbies><xsl:value-of select="normalize-space()"/></hobbies>
</xsl:for-each>
</xsl:template>
Yet an earlier approach such as the one below did picked up the value 'fishing':
<xsl:template match="/">
<employee>
<xsl:for-each select="/ns:html/ns:body/ns:div[@id='content']/ns:p/ns:strong">
<xsl:choose>
<xsl:when test="contains(.,'Hobbies:')">
<hobbies><xsl:value-of select="../ns:a"/></hobbies>
</xsl:when>
<xsl:otherwise>
<hobbies>None</hobbies>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>>
</employee>
</xsl:template>
Naturally, I would like to use the pattern matching approach (later) to complete the extraction of all element values in the same document.
Again, your invaluable suggestion is much appreciated.
Jack
From: Jack Bush [mailto:netbeansfan@yahoo.com.au]
Sent: 27 January 2009 13:03
To: Michael Kay; xml-dev@lists.xml.org
Subject: Re: [xml-dev] XSLT stylesheet looping through the same node (recursion?)Hi Michael,
Below is the output from your helpful suggestion:
( 1 ) <area>
( 2 ) <interest>Tennis</interest>
( 3 ) <interest>Movie</interest>
( 4 ) <interest>Swimming</interest>
( 5 ) </area>
( a ) <xsl:stylesheet version="1.0"
( f ) <xsl:template match="/">
( b ) xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
( c ) xmlns:ns="http://www.w3.org/1999/xhtml"
( d ) exclude-result-prefixes="ns">
( e )( g )<area>
( h )<xsl:apply-templates select="//ns:p"/>
( i ) </area>
( j )</xsl:template>
( k )<xsl:template match="ns:p[ns:strong='Nearest Hotels:']">
( l ) <xsl:for-each select="text()[normalize-space() != '']">
( m )<nearest_hotels><xsl:value-of select="normalize-space()"/></nearest_hotels>
( n ) </xsl:for-each>
( o ) </xsl:template>
( p )<xsl:template match="ns:p"/>
( q )
( r )</xsl:stylesheet>
This is the closest thing to what I wanted except that I would it to co-exist with the existing working XSL statements:
( i ) I could not getting another list of element values (e.g.. favourite songs...) that comes immediately after the <Interest> element. This may be due to the context node having been changed by when running the aboved stylesheet.
( ii ) There are other element values that I need to retrieve from the same document, where some is made up of a single value while others may have multiple occurrences. I will need to some how include the aboved code segment into the following existing working stylesheet responsible for retrieving other single element values, using the current context node where possible:
<xsl:template match="/">
<area>
<xsl:for-each select="/ns:html/ns:body/ns:div[@id='content']/ns:p/ns:strong">
<xsl:if test="contains(.,'Firstname:')">
<xsl:choose>
<xsl:when test="contains(.,'Firstname:')">
<firstname><xsl:value-of select="../ns:a"/></firstname>
</xsl:when>
<xsl:otherwise>
<firstname>Unknown</firstname>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:if test="contains(.,'Surname:')">
<xsl:choose>
<xsl:when test="contains(.,'Surname:')">
<surname><xsl:value-of select="../text()"/></surname>
</xsl:when>
<xsl:otherwise>
<surname>Unknown</surname>
</xsl:otherwise>
</xsl:choose>
.......
Thank you so much for the on-going guidances,
Jack
From: Michael Kay <mike@saxonica.com>
To: Jack Bush <netbeansfan@yahoo.com.au>; xml-dev@lists.xml.org
Sent: Tuesday, 27 January, 2009 12:54:23 AM
Subject: RE: [xml-dev] XSLT stylesheet looping through the same node (recursion?)
It looks to me as if you would be better off using pattern matching<xsl:template match="/">
<area>
<xsl:apply-templates select="//p"/>
</area>
</xsl:template>
<xsl:template match="ns:p[ns:strong='Interest:']"><xsl:for-each select="text()[normalize-space() != '']"><interest><xsl:value-of select="normalize-space()"/></interest></xsl:for-each></xsl:template><xsl:template match="ns:p"/>Michael Kay
From: Jack Bush [mailto:netbeansfan@yahoo.com.au]
Sent: 26 January 2009 13:31
To: xml-dev@lists.xml.org
Subject: [xml-dev] XSLT stylesheet looping through the same node (recursion?)Hi All,
I would like to get all the content/text in <p> node from the XML document where <p> has a child node <strong>Interest:<strong>. Below is the listing of both XML document and XSLT stylesheet:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html (View Source for full doctype...)>
- <html xmlns="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml">
- <head>
- <body
........
- ><div id="container">
+ <div id="header">
<div id="postmark" />
- <div id="content">
+ <div id="as1">
........
<h1>Employee Detail</h1>
- <p>
<strong>Interest:</strong>
<br />
Tennis
<br />
Movie
<br />
Swimming
<br />
......
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="ns">
<xsl:template match="/">
<area>
- <xsl:for-each select="/ns:html/ns:body/ns:div[@id='content']/ns:p/ns:strong">
- <xsl:if test="contains(.,'Interest:')">
- <xsl:choose>
- <xsl:when test="contains(.,'Interest:')">
- <interest>
<xsl:value-of select="../text()" />
</interest>
</xsl:when>
- <xsl:otherwise>
<interest>Unknown</interest>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
The transformation process produces the following output:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<title>Employee Detail</title>
<body>
<h1>Employee Detail</h1>
<interest>Tennis</interest>
</body>
</title>
</html>
One possible solution is by using recursion to go through the list of values on nodes but I am cannot think of how this could be done. Perhaps my difficulty is that I don’t know how to navigate down the list of interest of the same node using xsl command. Most of the Googled articles consisted of searching for the same type of element a cross multiple nodes, where as I am looking all the values (same type anyway) in a single node.
Below is the JDOM XPath solution to get the same list of values:
XPath interestxpath = XPath.newInstance("/ns:html/ns:body/ns:div[@id='content']/ns:p[10]/node()");
interestxpath.addNamespace("ns", "http://www.w3.org/1999/xhtml");
java.util.List interest_list = interestxpath.selectNodes(employeejdomDocument);
Iterator interest_iterator = interest_list.iterator();
while (interest_iterator..hasNext())
{
interest_value = ((org.jdom.Content)interest_iterator.next()).getValue();
……
I am new to XSLT stylesheet transformation and can do with some guidances.
Many thanks again,
Jack
Stay connected to the people that matter most with a smarter inbox. Take a look.
Stay connected to the people that matter most with a smarter inbox. Take a look.