2010-03-16 7 views
10

मेरी मदद करो, Stackoverflow!एक्सएसएलटी के साथ .NET एक्सटेंशन ऑब्जेक्ट्स - संग्रह पर पुनरावृत्ति कैसे करें?

मेरे पास एक साधारण .NET 3.5 कंसोल ऐप है जो कुछ डेटा पढ़ता है और ईमेल भेजता है। मैं एक एक्सएसएलटी स्टाइलशीट में ईमेल प्रारूप का प्रतिनिधित्व कर रहा हूं ताकि हम ऐप को फिर से सम्मिलित किए बिना ईमेल के शब्द को आसानी से बदल सकें।

हम एक्सटेंशन वस्तुओं का उपयोग कर रहे XSLT को डेटा पास करने के लिए जब हम परिवर्तन लागू होते हैं: -:

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

ऊपर काम करता है

<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"> 

इस तरह से, हम जैसे बयानों हो सकता है ठीक।

// 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, या जो कुछ भी मैं में पारित करने के लिए कोशिश

तो, मेरे सवाल कर रहे हैं:

  1. मैं अपने एक्सएसएलटी में संग्रह में कैसे जा सकता हूं?

  2. मैं xsl के लिए क्या डालूं: xsl के अंदर चयन = का चयन करें: प्रत्येक के लिए?

मैं क्या असंभव करने के लिए कोशिश कर रहा हूँ है?


संपादित करें: के बाद मैं दो जवाब नीचे देखा, मैं क्रिस हाइंस 'कोड लिया और यह बहुत थोड़ा मेरी आवश्यकताओं के अनुरूप करने के लिए संशोधित। समाधान इस प्रकार है:

// 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> 

पूरी तरह से काम किया!

उत्तर

9

एक्सएसएलटी प्रत्येक के लिए एक नोड सेट को फिर से चालू करने की अपेक्षा करता है - आप सीधे अपने सी # कोड से सरणी को वापस नहीं भेज सकते हैं। आपको 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; 
} 
+0

धन्यवाद! मैं अभी इसे जांचने जा रहा हूं। – Pandincus

+0

@ क्रिस हाइन्स: आपका उत्तर और नमूना कोड बिल्कुल वही था जो मुझे चाहिए था। मैंने आपके नमूना कोड को थोड़ा सा संशोधित किया क्योंकि आप XmlElement (स्पष्ट रूप से) की मान संपत्ति सेट नहीं कर सकते हैं, और मैं अपना कोड क्षण में मेरे उत्तर में पोस्ट करूंगा। ओबेलिक्स का समाधान भी सही था, लेकिन मैं केवल एक जवाब स्वीकार कर सकता हूं और नमूना कोड वास्तव में ऊपर और परे था - मेरे जीवन को आसान बना दिया। धन्यवाद क्रिस! – Pandincus

+0

तदनुसार संशोधित - मैंने वास्तव में कोड नहीं चलाया, बस इसे * ब्लश * लिखा था। –

2

documentation कहता है:

The parameter should correspond to a W3C type. The following table shows the W3C types, either XPath or XSLT, and the corresponding.NET class.

और सूचियों निम्नलिखित प्रकार:

  • स्ट्रिंग
  • बूलियन
  • संख्या
  • परिणाम ट्री टुकड़ा
  • नोड सेट
  • नोड

तो, इस सवाल का जवाब नहीं आप नहीं कर सकते हैं अच्छी तरह से कम से कम सीधे नहीं है ...। लेकिन आपके मामले में सबसे अच्छी शर्त है, आईएमएचओ, नोड या नोड सेट।

+0

' कॉल करने की आवश्यकता नहीं है, मैंने दस्तावेज़ को क्यों नहीं देखा XsltArgumentList.AddParam के लिए मेरे बाहर है। (दिन में बहुत देर हो चुकी है?) मैं एक नोड या नोडसेट लौटने की जांच कर रहा हूं और देख सकता हूं कि यह काम करता है या नहीं। धन्यवाद! – Pandincus

संबंधित मुद्दे