Jump to content

XHTML in XSL Help


kvnmck18

Recommended Posts

When using the following code...

<?php$xmlfile = "xml.xml";$xslfile = "xsl.xsl";if ($_GET['whatever']) {$expression= array("whatever" => $_GET['whatever']);} else {$expression=NULL;} $args = $expression;$engine = xslt_create();$output = xslt_process($engine, $xmlfile, $xslfile, NULL, NULL, $args);print $output;xslt_free($engine);?>
...Is there anyway so when the XML/XSL are put together to make them exported in xhtml?As of right now it comes up as this: <?xml version="1.0" encoding="UTF-8"?> then it goes to the html. I used css and I have "margin:0 auto" (because I want it to be centered) and it is not working it's like its "margin:0"Is there anyway so when they are put together to have it encoded as: <html xmlns="http://www.w3.org/1999/xhtml"> ?Or some other way to have my css work compatiably with XSL to center the div?---------------------And to another subject how can you get a table to be 2 columns when using xslt?I only know how to do this when there is more data being added:
<table><xsl:for-each select="//whatever"><tr><td><xsl:value-of select="one"/></td><td><xsl:value-of select="two"/></td></tr></xsl:for-each></table>

But I really want it to be more like this:

<table><xsl:for-each select="//whatever"><tr><td><xsl:value-of select="one"/></td><td><xsl:value-of select="one"/></td></tr></xsl:for-each></table>

Is that clear what I'm trying to say? Like have the xsl "expand" the xml data down and one cell over to the right.

Link to comment
Share on other sites

You can use the line:

header("Content-type: application/xhtml+xml");

where the contents of the header() function can be any sort of HTTP header. In this case, it's the MIME type.To remove the XML prolog in both MIME types, you can use

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

In the XSLT.Or if you want to remove it only for IE6 and with text/html, you can use this code (made by yours truly few weeks ago):

//Checks the transformation$result = ereg_replace(' xmlns=""',NULL,$transformation);	//Remove the empty xmlns attributes that sometimes get createdif (ereg('application\/xhtml\+xml',$_SERVER["HTTP_ACCEPT"])) {	//Checks if the user agent supports XHTML's MIME typeheader("Content-type: application/xhtml+xml");	//Sets that MIME type if supported}elseif(ereg("MSIE 6.0",$_SERVER["HTTP_USER_AGENT"])) {	//Checks if the user agent is IE6 baseed$result = ereg_replace('\<\?xml version="1.0" encoding="windows-1251"\?\>',NULL,$transformation);	//Removes the XML prolog for IE6}//Show the result in the browser.echo $result;

Where $transformation is the result of the XSLT processing. Unfortunatly, in this current form, you have to edit:

\<\?xml version="1.0" encoding="windows-1251"\?\>

so that it matches your actual XML prolog. Detecting XML prologs dynamically is a question of using the XML writter with which I'm not that experienced yet or a more complex regular expression which in my case seemed pointless.If you want to use multiple columns with the same type of node (both elements called "one"?), simply use the xsl:for-each. If it's the exact same element (one element called "one" used two times), I think there's not more precise way then your second example. If you're worried about flexibility (say you want to rename your element, and still call it multiple times over), you can store it's name in a variable and use this name for the selection, like this:

<table><xsl:for-each select="//whatever"><xsl:variable name="value" select="one"/><tr><td><xsl:value-of select="$value"/></td><td><xsl:value-of select="$value"/></td></tr></xsl:for-each></table>

With this, adjusting the single select statement at the variable will affect both cells.There are of course other ways, but it depends on what you need.

Link to comment
Share on other sites

That's all brilliant. Listen to this... I'm not one bit, there was no problem at all. It was a simple CSS typo, haha. But I need to add your last comments to my favorites. You need to write a book, a) you know everything :) you explain it clearlyThanks bud.

Link to comment
Share on other sites

That's all brilliant. Listen to this... I'm not one bit, there was no problem at all. It was a simple CSS typo, haha. But I need to add your last comments to my favorites. You need to write a book, a) you know everything :) you explain it clearlyThanks bud.
This script is in the front of my bag'o'tricks. When I make my own site (I don't have much time for working on it though) I'll publish my whole bag'o'tricks there and a lot more (for which no one has asked yet).
Link to comment
Share on other sites

I over-looked your one example

<table><xsl:for-each select="/"><xsl:variable name="value" select="@one"/><tr><td><xsl:value-of select="$value"/></td><td><xsl:value-of select="$value"/></td></tr></xsl:for-each></table>

...this was my fault, I actually want it to be froma list of similiar nodes but different values. (I'm really tired and really annoyed right now... I can't think well)Example:xml:[/code]<whatever><here one="this is the value" /><here one="this is another value" /><here one="dfdjksfjlsdjf" /><here one="this is dsfsdafsdf" /></whatever>

so it makes:[code]<table><tr><td>this is the value</td><td>this is another value"</td></tr><tr><td>dfdjksfjlsdjf</td><td>this is dsfsdafsdf</td></tr></table>

SOrry again I'm just in a bad mood currently. SO frustrated with everything in my life.

Link to comment
Share on other sites

  • 3 weeks later...

Hi all, this topic seems to be related to what I am trying to obtain. Actually perhaps the answer is already there, but I am so XSL-impaired that I cannot see it.So, what I have is a collection like this

<items> <item>   <attr> A </attr> </item> <item>   <attr> B </attr> </item> <item>   <attr> C </attr> </item> <item>   <attr> D </attr> </item> <item>   <attr> E </attr> </item></items>

and I would like to display all of the attrs in a two-column table, like thisA BC DE (possibly nothing)I am thinking of something involving the mod function (mod #of columns in the table, in this case)but I am not able to sort it out. I have tried to look in the forum for similar problems, but I amnot even sure how to formulate the question...Can someone help me?ThanksF

Link to comment
Share on other sites

The following XSLT code creates a dynamic HTML table. You define the number of columns that you want and it will create as many TRs as needed. This code use node-sets and recursion but is fairly straight forward. I am quite proud of this one as it had been my plague for years to do this. Feel free to adjust as needed.

<xsl:stylesheet	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"	xmlns:msxsl="urn:schemas-microsoft-com:xslt"	version="1.0">	<xsl:param name="CellsPerRow">3</xsl:param>	<xsl:template match="/">		<xsl:variable name="Data" select="//item" />			<!-- create a node-set of the data to display -->		<xsl:call-template name="DoTable">			<xsl:with-param name="Data" select="$Data"/>		</xsl:call-template>	</xsl:template>	<xsl:template name="DoTable">		<xsl:param name="Data"/>		<xsl:if test="count(msxsl:node-set($Data)//attr) > 0 ">		<!-- nothing to do if the node-set is empty -->			<table border="1" cellspacing="0" cellpadding="0">		<!-- start the table here -->				<xsl:call-template name="DoData">					<!-- Call the row builder for row one -->					<xsl:with-param name="RowNumber">1</xsl:with-param>	<!-- Start with row one -->					<xsl:with-param name="TotalRows" select="ceiling(count(msxsl:node-set($Data)//attr) div $CellsPerRow) "/> <!-- Calculate the total number of rows that will be built -->					<xsl:with-param name="Data" select="$Data"/>				</xsl:call-template>			</table>		</xsl:if>	</xsl:template>	<xsl:template name="DoData">		<xsl:param name="RowNumber"/>			<!-- This routine is recursed into incrementing the row count each time -->		<xsl:param name="TotalRows"/>			<!-- value is constant, calculated by first caller -->		<xsl:param name="Data"/>		<xsl:variable name="EndPos" select="$RowNumber * $CellsPerRow"/>		<!-- This the end position of the node-set that we will position on -->		<xsl:variable name="BegPos" select="$EndPos - $CellsPerRow + 1"/>		<!-- This the beginning position of the node-set that we will position on, note that the end is calculated first -->		<tr>	<!-- add a row to the table -->			<xsl:apply-templates select="msxsl:node-set($Data)[position() >= $BegPos and position() <= $EndPos]" />  <!-- call the routine to add as many cells as needed based on the begin and end positions -->		</tr>		<xsl:if test="$RowNumber < $TotalRows">		<!-- If we have less rows than total, recurse into this routine and increment the row counter -->			<xsl:call-template name="DoData">				<xsl:with-param name="RowNumber" select="$RowNumber + 1"/>				<xsl:with-param name="TotalRows" select="$TotalRows" />				<xsl:with-param name="Data" select="$Data"/>			</xsl:call-template>		</xsl:if>	</xsl:template>	<xsl:template match="attr">					<!-- Build each cell here -->		<td><xsl:value-of select="." /></td>	</xsl:template></xsl:stylesheet>

Link to comment
Share on other sites

@aalbetski your code uses an extension. See the code I'm giving. It doesn't have a single one. The second one (not made by myself) is not even using DOE.

Link to comment
Share on other sites

It can be removed and the data accessed without the node-set. As I said, modify as needed.I'm a big fan of recursion and always love to try and use it when I can. As you know, there are many ways to solve a problem. This is just another option.edited: I have revised the above code, removing the node-set references. Personally, I think that passing the node-set as a variable renders this as more resuable, but here it is for those who may want to see how it works.

<xsl:stylesheet	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"	 version="1.0">	<xsl:param name="CellsPerRow">3</xsl:param>	<xsl:template match="/">		<xsl:call-template name="DoTable" />	</xsl:template>	<xsl:template name="DoTable">		<xsl:if test="count(//item) > 0 ">							<!-- nothing to do if empty -->			<table border="1" cellspacing="0" cellpadding="0">		<!-- start the table here -->				<xsl:call-template name="DoData">					<!-- Call the row builder for row one -->					<xsl:with-param name="RowNumber">1</xsl:with-param>		<!-- Start with row one -->					<xsl:with-param name="TotalRows" select="ceiling(count(//attr) div $CellsPerRow) "/> <!-- Calculate the total number of rows that will be built -->				 </xsl:call-template>			</table>		</xsl:if>	</xsl:template>	<xsl:template name="DoData">		<xsl:param name="RowNumber"/>			<!-- This routine is recursed into incrementing the row count each time -->		<xsl:param name="TotalRows"/>			<!-- value is constant, calculated by first caller -->		<xsl:variable name="EndPos" select="$RowNumber * $CellsPerRow"/>		<!-- This the end position of the node-set that we will position on -->		<xsl:variable name="BegPos" select="$EndPos - $CellsPerRow + 1"/>		<!-- This the beginning position of the node-set that we will position on, note that the end is calculated first -->		<tr>	<!-- add a row to the table -->			<xsl:apply-templates select="//item[position() >= $BegPos and position() <= $EndPos]/attr" />  <!-- call the routine to add as many cells as needed based on the begin and end positions -->		</tr>		<xsl:if test="$RowNumber < $TotalRows">		<!-- If we have less rows than total, recurse into this routine and increment the row counter -->			<xsl:call-template name="DoData">				<xsl:with-param name="RowNumber" select="$RowNumber + 1"/>				<xsl:with-param name="TotalRows" select="$TotalRows" />			</xsl:call-template>		</xsl:if>	</xsl:template>	<xsl:template match="attr">					<!-- Build each cell here -->		<td><xsl:value-of select="." /></td>	</xsl:template></xsl:stylesheet>

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...