Recursion 如何递归获取XmlProvider的所有XElement子级

Recursion 如何递归获取XmlProvider的所有XElement子级,recursion,f#,f#-data,fsharp.data.typeproviders,Recursion,F#,F# Data,Fsharp.data.typeproviders,我正试图从以下XML中使用F为C#构建一个动态类型/类生成器 <config target="string"> <protocol>string</protocol> <about_path>string</about_path> <about_content> <name_path>string</name_path> <id_path&

我正试图从以下XML中使用F为C#构建一个动态类型/类生成器

<config target="string">
    <protocol>string</protocol>
    <about_path>string</about_path>
    <about_content>
        <name_path>string</name_path>
        <id_path>string</id_path>
        <version_path>string</version_path>
    </about_content>
</config>
我已经试着在F#中处理递归,但是我被这样的非工作代码卡住了(
e
应该是
parsedValue.XElement

让rec变平(e:System.Xml.Linq.XElement)(out:List)=
如果e.has元素
然后对于e.元素中的内部->展平(内部)
else e.Name.LocalName

我需要的是关于如何将
e.Name.LocalName
值作为递归的结果收集到序列/列表中的提示。我还可以接受在末尾有一个
XElement
s列表。

函数
flatten
需要返回一个序列,而不是一件事

对于包含子元素的元素,需要为每个元素调用
展平
,然后合并所有结果:

e.Elements() |> Seq.map flatten |> Seq.concat
(请注意,
XElement.Elements
是一个方法,而不是属性;因此,需要添加
()
来调用它)

对于单个元素,只需返回以单个元素序列包装的名称:

Seq.singleton e.Name.LocalName
let rec flatten (e : System.Xml.Linq.XElement) = 
    seq {
        if e.HasElements then 
            for i in e.Elements() do 
                yield! flatten i
        else 
            yield e.Name.LocalName
    }
总而言之:

let rec flatten (e : System.Xml.Linq.XElement) = 
    if e.HasElements 
    then e.Elements() |> Seq.map flatten |> Seq.concat
    else Seq.singleton e.Name.LocalName
(还请注意,我已经删除了您的
out
参数,我认为该参数不是参数,而是试图声明函数的返回类型;可以省略它;作为参考,F#中的函数返回类型是在函数签名后用冒号声明的,例如
let F(x:int):int=x+5


如果您更喜欢命令式样式,可以使用
seq
计算表达式
yield
将生成一个元素,而
yield将产生产生另一序列的每个元素的效果:

Seq.singleton e.Name.LocalName
let rec flatten (e : System.Xml.Linq.XElement) = 
    seq {
        if e.HasElements then 
            for i in e.Elements() do 
                yield! flatten i
        else 
            yield e.Name.LocalName
    }

工作起来很有魅力,我很喜欢那种不那么刻板的风格:)
let rec flatten (e : System.Xml.Linq.XElement) = 
    seq {
        if e.HasElements then 
            for i in e.Elements() do 
                yield! flatten i
        else 
            yield e.Name.LocalName
    }