在XSLT扩展方法的返回值上使用Xpath
本文关键字:Xpath 返回值 XSLT 扩展 方法 | 更新日期: 2023-09-27 18:01:36
我有一个由扩展方法返回的xml。请问有人能帮我在这个xml上使用<xsl:for-each>
吗?
public class CustomObj
{
//function that gets called from XSLT
public XPathNodeIterator GetResultTable()
{
DataTable table = new DataTable("Table1");
table.Columns.Add("SourceCity");
table.Columns.Add("DestinationCity");
table.Columns.Add("Fare");
table.Rows.Add(new object[] { "New York", "Las Vegas", "100" });
table.Rows.Add(new object[] { "New York", "London", "200" });
table.Rows.Add(new object[] { "New York", "New Delhi", "250" });
StringWriter writer = new StringWriter();
table.WriteXml(writer);
XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("Root");
root.InnerXml = writer.ToString();
doc.AppendChild(root);
return doc.CreateNavigator().Select("root");
}
}
我想遍历这个xml。谁来帮帮我。我是XSLT的新手,如果您能提供有关给定xml本身的示例,我将不胜感激。
有两件事需要注意:
-
将转换应用于调用方法
GetResultTable()
的结果比通过扩展函数获得结果要自然得多。 -
如前所述,
GetResultTable()
方法根本不返回任何节点:在语句
,
return doc.CreateNavigator().Select("root");
Select()
方法不选择任何东西,因为doc
中没有root
元素。没有选择名为Root
的元素,因为XML和XPath是区分大小写的。
另一个观察结果是,根本没有必要在XSLT转换中使用xsl:for-each
——在大多数情况下,这被认为不是一个好的实践。
话虽如此,下面是这个问题对的完整代码:
namespace TestXml
{
using System;
using System.Data;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
class Program
{
static void Main(string[] args)
{
CustomObj co = new CustomObj();
XPathNodeIterator xpni = co.GetResultTable();
XslCompiledTransform xslt = new XslCompiledTransform(true);
xslt.Load(@"..'..'My.xslt");
XsltArgumentList xargs = new XsltArgumentList();
xargs.AddExtensionObject("my:extension", co);
XmlDocument fakeDoc = new XmlDocument();
fakeDoc.LoadXml("<t/>");
StringWriter sw = new StringWriter();
xslt.Transform(fakeDoc.CreateNavigator(), xargs, sw);
string result = sw.ToString();
Console.Write(result);
}
}
public class CustomObj
{ //function that gets called from XSLT
public XPathNodeIterator GetResultTable()
{
DataTable table = new DataTable("Table1");
table.Columns.Add("SourceCity");
table.Columns.Add("DestinationCity");
table.Columns.Add("Fare");
table.Rows.Add(new object[] { "New York", "Las Vegas", "100" });
table.Rows.Add(new object[] { "New York", "London", "200" });
table.Rows.Add(new object[] { "New York", "New Delhi", "250" });
StringWriter writer = new StringWriter();
table.WriteXml(writer);
XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("Root");
root.InnerXml = writer.ToString();
doc.AppendChild(root);
return doc.CreateNavigator().Select("Root");
}
}
}
和文件My.xslt
:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:extension"
exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<html>
<table border="1">
<tr>
<td>Source</td>
<td>Destination</td>
<td>Fare</td>
</tr>
<xsl:apply-templates select="my:GetResultTable()/*/Table1"/>
</table>
</html>
</xsl:template>
<xsl:template match="Table1">
<tr>
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="Table1/*">
<td>
<xsl:apply-templates/>
</td>
</xsl:template>
</xsl:stylesheet>
当应用程序执行时,生成所需的正确结果:
<html>
<table border="1">
<tr>
<td>Source</td>
<td>Destination</td>
<td>Fare</td>
</tr>
<tr>
<td>New York</td>
<td>Las Vegas</td>
<td>100</td>
</tr>
<tr>
<td>New York</td>
<td>London</td>
<td>200</td>
</tr>
<tr>
<td>New York</td>
<td>New Delhi</td>
<td>250</td>
</tr>
</table>
</html>