简体   繁体   中英

How can you display values within a node-set when retrieving them using a function?

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 &gt; 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 the for-each select statement changing it to "$rows/MyDataSet/*".
  • for the for-each select statement changing it to "$rows/MyDataSet/MyTableData".
  • for the 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">&lt;MyDataSet&gt;Data&lt;/MyDataSet&gt;</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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM