微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – .NET扩展对象与XSLT – 如何迭代集合?

帮我,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."

或列表,或IEnumerable,或任何我尝试传入.

所以我的问题是:

>如何传递一个集合到我的XSLT?
>在xsl:for-each中为xsl:value提供了select =“”?

是我试图做的不可能吗

编辑:在我看到下面的两个答案之后,我采取了克里斯·海因斯的代码,并修改了它,以适应我的需要.解决方法如下:

// 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 – 每个都希望一个节点集迭代 – 你不能直接从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;
}

原文地址:https://www.jb51.cc/csharp/95367.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐