Подтвердить что ты не робот

F # XML-синтаксический анализ

этот код С#, вероятно, не самый эффективный, но получает то, что я хочу сделать.

Как выполнить то же самое в коде F #?

    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 ;
        }               
    }
4b9b3361

Ответ 1

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 с пустой строкой.

Ответ 2

Вот аналогичный код для этого в F #. Я уверен, что один из F # ninja поставит лучшую версию здесь через минуту.

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()

Ответ 3

То же самое с F # Data XML Type Provider:

type EmailList = XmlProvider<"""<EmailList><Email>email</Email><Email>email</Email></EmailList>""">
let data = EmailList.Parse("""
    <EmailList>
        <Email>[email protected]</Email>
        <Email>[email protected]</Email>
    </EmailList>
    """)

let emailList = data.Emails |> String.concat Environment.NewLine

Ответ 4

Если вы посмотрите на свой код, у вас будет несколько вещей. Первый - это загрузка коллекции для узлов электронной почты, а вторая - фактически что-то значимое с ними.

Сначала вы хотите, чтобы ваша функция возвращала коллекцию. Что-то вроде (и я нахожусь на своем 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();
        }               
    }
}

Теперь возникает вопрос, что вы хотите сделать с этой коллекцией. В приведенном выше примере вы объединили его или в основном сохраняете состояние.

С точки зрения С# вы можете начать использовать такие вещи, как ответы этого вопроса (используя LINQ) и this один.

С точки зрения F # у вас теперь есть список и вы можете просто использовать обычные процедуры для списка, например этот или здесь.

Вы также можете посмотреть LINQ to XML (или на 5-минутный обзор), чтобы получить больше идей.

Ответ 5

Как насчет чего-то по строкам:

#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