I have a stylesheet called FourColumnTable that I want to use as a table template. At the moment it looks like this and uses the xml shown below it:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl"http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template name="FourColumnTable">
<xsl:param name="rows" />
<table>
<tbody>
<tr>
<td>Name</td>
<td>Age</td>
<td>Name</td>
<td>Age</td>
</tr>
</tbody>
</table>
<xsl:variable name="itemCount" select="count($rows/*)" />
<xsl:if test="$itemCount > 1">
<xsl:for-each select="$rows/MyTableData">
<table>
<tbody>
<tr>
<td><xsl:value-of select="name" /></td>
<td><xsl:value-of select="age" /></td>
<td>blank for now</td>
<td>blank for now</td>
</tr>
</tbody>
</table>
</xsl:for-each>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
The data is retrieved using a function that returns some xml as a string. The xml looks like this:
<MyDataSet>
<MyTableData>
<name>Bob</name>
<age>25</age>
</MyTableData>
<MyTableData>
<name>Karen</name>
<age>36</age>
</MyTableData>
<MyTableData>
<name>Frank</name>
<age>58</age>
</MyTableData>
</MyDataSet>
I have an email template that currently works and that I now want to put this table into it. So at the moment I'm doing the following:
<xsl:template name="CustomerData">
<xsl:call-template name="FourColumnTable">
<xsl:with-param name="rows" select="msxml:node-set(myFunctions:GetCustomerData())" />
</xsl:call-template>
</xsl:template>
At the moment this seems to create a node-set, but when I try and use it in the for-each
it doesn't show any values. I've tried removing the if statement
and then doing the following:
for-each
select statement changing it to "$rows/MyDataSet/*". for-each
select statement changing it to "$rows/MyDataSet/MyTableData". for-each
select statement changing it to "$rows/node()" and then in the first column for the select statement of the 'value-of' adding "$rows/node()". This displayed all of the data as per the xml, so I know $rows at least has the data. I've tried variations of the above but those seem to be the main tests worth mentioning. What I can't understand is why it will return the data for everything, but I'm unable to loop through for specific nodes (MyTableData nodes). Help please.
UPDATE
Here is my function GetCustomerData()
:
public string GetCustomerData()
{
var sb = new StringBuilder();
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(this.GetAllCustomerData());
var nodeList = xmlDoc.SelectNodes("/MyTableData");
if (nodeList != null && nodeList.Count > 0)
{
foreach (XmlNode node in nodeList)
{
sb.Append(node.InnerText + EnvironmentNewLine);
}
}
return sb.ToString();
}
I'm guessing this needs to return an XmlDocument
instead? However, my GetAllCustomerData method returns a lot more than what I need, which is why I select the nodes I want. Can I take this XmlNodeList
and turn that into an XmlDocument?
UPDATE 2
I opted to change my function to simply return the xml document as is and then in my table template alter what nodes I iterate over within the foreach
statement like this:
public XmlDocument GetCustomerData()
{
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(this.GetAllCustomerData());
return xmlDoc;
}
This allowed me to iterate over what I needed.
It looks like your custom function is not returning an xml document or document fragment, it's probably just a string, but without being able to see that function I can't say for sure.
In other words, you've got the equivalent of
<xsl:param name="rows"><MyDataSet>Data</MyDataSet></xsl:param>
instead of
<xsl:param name="rows"><MyDataSet>Data</MyDataSet></xsl:param>
And you're not able to process is as XML, because it's not, it's just the markup. Calling node-set on it doesn't parse it into XML, it turns it into a set of one text node.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.