2008-12-02 6 views
20

यह सी # कोड शायद सबसे अधिक कुशल नहीं है लेकिन मुझे वह चाहिए जो मैं चाहता हूं।एफ # एक्सएमएल पार्सिंग

मैं एफ # कोड में वही चीज़ कैसे पूरा करूं?

string xml = " <EmailList> " + 
       "  <Email>[email protected]</Email> " + 
       "  <Email>[email protected]</Email> " + 
       " </EmailList> "; 

    XmlDocument xdoc = new XmlDocument(); 
    XmlNodeList nodeList; 
    String emailList = string.Empty; 
    xdoc.LoadXml(xml); 
    nodeList = xdoc.SelectNodes("//EmailList"); 
    foreach (XmlNode item in nodeList) 
    { 
     foreach (XmlNode email in item) 
     { 
      emailList += email.InnerText.ToString() + Environment.NewLine ; 
     }    
    } 

उत्तर

47
let doc = new XmlDocument() in 
    doc.LoadXml xml; 
    doc.SelectNodes "/EmailList/Email/text()" 
     |> Seq.cast<XmlNode> 
     |> Seq.map (fun node -> node.Value) 
     |> String.concat Environment.NewLine 

आप वास्तव में अंतिम अनुगामी न्यू लाइन आप नक्शे और String.concat रिक्त स्ट्रिंग के साथ में यह भी जोड़ सकते हैं चाहते हैं।

1

यदि आप अपना कोड देखते हैं, तो आपके पास कुछ चीजें चल रही हैं। पहला ईमेल नोड्स के लिए संग्रह लोड कर रहा है, और दूसरा वास्तव में उनके साथ सार्थक कुछ कर रहा है।

सबसे पहले, आप अपने फ़ंक्शन को एक संग्रह वापस करना चाहते हैं। (और मैं अपने Mac पर हूँ, इसलिए यह काम नहीं कर सकते हैं) की तरह कुछ:


List<string> EmailAddresses(string xml) 
{ 
    XmlDocument xdoc = new XmlDocument(); 
    XmlNodeList nodeList; 
    String emailList = string.Empty; 
    xdoc.LoadXml(xml); 
    nodeList = xdoc.SelectNodes("//EmailList"); 
    foreach (XmlNode item in nodeList) 
    { 
     foreach (XmlNode email in item) 
     { 
      yield email.InnerText.ToString(); 
     }    
    } 
} 

अब सवाल क्या आपको लगता है कि संग्रह के साथ क्या करना चाहते हैं के आसपास आता है। उपरोक्त आपके उदाहरण में, आप इसे संयोजित कर रहे थे, या मूल रूप से राज्य संग्रहित कर रहे थे।

सी # परिप्रेक्ष्य से, आप this question (LINQ का उपयोग करके) और this one के उत्तरों जैसे चीजों का उपयोग शुरू कर सकते हैं।

एक एफ # परिप्रेक्ष्य से, अब आपके पास एक सूची है और this one या here जैसी सूची के लिए सामान्य प्रक्रियाओं का उपयोग कर सकते हैं।

आप कुछ और विचार पाने के लिए LINQ to XML (या 5 minute overview पर) भी देख सकते हैं।

1

कैसे की तर्ज पर कुछ के बारे में:

#light 
open System.Xml 

let xml = "..." 

let emailList = 
    let xdoc = new XmlDocument() 
    xdoc.LoadXml(xml) 

    let mutable list = [] 
    let addEmail e = list <- e :: emailList 

    xdoc.SelectNodes("//EmailList") 
    |> IEnumerable.iter(fun(item:XmlNode) -> 
     item 
     |> IEnumerable.iter(fun(e:XmlNode) -> 
      addEmail e.InnerText;())) 

    list 
+0

? मैं संकलन करने के लिए IENumerable लाइनों नहीं मिल सकता है। आप इस प्रकार से कहां से मिल रहे हैं? – JaredPar

+0

क्या Seq.iter के बजाय IEnumerable.iter का उपयोग करने का कोई विशेष कारण है? दोनों के बीच कोई अंतर नहीं है, सेक अधिक मूर्खतापूर्ण एफ # है। – Juliet

+0

नहीं, मैंने कुछ वर्षों में एफ # प्रोग्राम नहीं किया है। :-) –

6

यहाँ समान कोड एफ # में यह करने के लिए है। मुझे यकीन है कि एफ # निंजा की एक मिनट में एक बेहतर संस्करण होगा।

open System.Xml 

let getList x = 
    let getDoc = 
     let doc = new XmlDocument() 
     doc.LoadXml(x) |> ignore 
     doc 
    let getEmail (n:XmlNode) = n.InnerText.ToString() 
    let doc = getDoc 
    let build = new System.Text.StringBuilder() 
    doc.SelectNodes("//EmailList") 
     |> Seq.cast<XmlNode> 
     |> Seq.map (fun n -> n.ChildNodes) 
     |> Seq.map_concat (Seq.cast<XmlNode>) 
     |> Seq.map(fun (n:XmlNode) -> getEmail n) 
     |> Seq.iter (fun e -> build.AppendLine(e) |> ignore) 
    build.ToString()