Recursion 如何递归获取XmlProvider的所有XElement子级
我正试图从以下XML中使用F为C#构建一个动态类型/类生成器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&
<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
}