gpt4 book ai didi

c# - .NET Extension Objects with XSLT——如何遍历一个集合?

转载 作者:可可西里 更新时间:2023-11-01 09:07:48 24 4
gpt4 key购买 nike

帮助我,Stackoverflow!

我有一个简单的 .NET 3.5 控制台应用程序,它可以读取一些数据并发送电子邮件。我在 XSLT 样式表中表示电子邮件格式,这样我们就可以轻松更改电子邮件的措辞,而无需重新编译应用程序。

当我们应用转换时,我们使用扩展对象将数据传递给 XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
xmlns:EmailNotification="ext:EmailNotification">

-- 这样,我们可以有这样的语句:

<p>
Dear <xsl:value-of select="EmailNotification:get_FullName()" />:
</p>

以上工作正常。我通过这样的代码传递对象(为简洁起见省略了一些不相关的代码):

// purely an example structure
public struct EmailNotification
{
public string FullName { get; set; }
}

// Somewhere in some method ...

var notification = new Notification("John Smith");

// ...

XsltArgumentList xslArgs = new XsltArgumentList();
xslArgs.AddExtensionObject("ext:EmailNotification", notification);

// ...

// The part where it breaks! (This is where we do the transformation)
xslt.Transform(fakeXMLDocument.CreateNavigator(), xslArgs, XmlWriter.Create(transformedXMLString));

因此,以上所有代码都有效。然而,我想变得有点花哨(总是我的垮台)并通过一个集合,这样我就可以做这样的事情:

<p>The following accounts need to be verified:</p>
<xsl:for-each select="EmailNotification:get_SomeCollection()">
<ul>
<li>
<xsl:value-of select="@SomeAttribute" />
</li>
</ul>
<xsl:for-each>

当我在扩展对象中传递集合并尝试转换时,出现以下错误:

"Extension function parameters or return values which have Clr type 'String[]' are not supported."

或 List,或 IEnumerable,或我尝试传入的任何内容。

所以,我的问题是:

  1. 如何将集合传递给我的 XSLT?

  2. 我应该为 xsl:for-each 中的 xsl:value-of select=""添加什么?

我想做的事是不可能的吗?


编辑:在看到下面的两个答案后,我采用了 Chris Hynes 的代码并对其进行了微调以满足我的需要。解决方法如下:

// extension object
public struct EmailNotification
{
public List<String> StringsSetElsewhere { private get; set; }
public XPathNavigator StringsNodeSet
{
get
{
XmlDocument xmlDoc = new XmlDocument();
XmlElement root = xmlDoc.CreateElement("Strings");
xmlDoc.AppendChild(root);
foreach (var s in StringsSetElsewhere)
{
XmlElement element = xmlDoc.CreateElement("String");
element.InnerText = s;
root.AppendChild(element);
}
return xmlDoc.CreateNavigator();
}
}
}

在我的 XSLT 中......

<xsl:for-each select="EmailNotification:get_StringsNodeSet()//String">
<ul>
<li>
<xsl:value-of select="." />
</li>
</ul>
</xsl:for-each>

完美运行!

最佳答案

XSLT for-each 需要一个节点集来迭代——您不能直接从 C# 代码传回一个数组。您应该返回一个 XPathNodeIterator。

像这样:

public static XPathNodeIterator GetSomeCollection()
{
XmlDocument xmlDoc = new XmlDocument();

string[] stringsToReturn = new string[] { "String1", "String2", "String3" };

XmlElement root = xmlDoc.CreateElement("Strings");

xmlDoc.AppendChild(root);

foreach (string s in stringsToReturn)
{
XmlElement el = xmlDoc.CreateElement("String");

el.InnerText = s;

root.AppendChild(el);
}

XPathNodeIterator xNodeIt = xmlDoc.CreateNavigator().Select(".");

return xNodeIt;
}

关于c# - .NET Extension Objects with XSLT——如何遍历一个集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2458349/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com