Ene*_*nes 13 xml f# linq-to-xml
F#新手
我有2个文件夹2个XML文件c:\root\a\file.xml和c:\root\b\file.xml
它们具有相同的结构:
<parent>
<property name="firstName">Jane</property>
<property name="lastName">...</property>
<property name="dateOfBirth">...</property>>
</parent>
Run Code Online (Sandbox Code Playgroud)
我需要选择具有名称的属性节点具有firstName值Jane的文件.
在F#中(可能通过使用System.Xml.Linq)我尝试了几种解决方案但到目前为止都没有.有人愿意帮忙吗?
Tom*_*cek 37
如果你能展示一些你尝试过的代码会很有用 - 有人可以解释问题是什么,所以你可以学到更多东西,而不是有人发布有用的代码.无论如何,您需要首先引用一些程序集System.Xml.Linq并打开命名空间.在F#interactive中,你可以像这样编写它(在F#项目中,只需使用Add Reference对话框):
#r "System.Core.dll"
#r "System.Xml.Linq.dll"
open System.Xml.Linq
Run Code Online (Sandbox Code Playgroud)
在F#中使用XLinq时,需要一个简单的实用程序函数将字符串转换为XName对象(表示元素/属性名称).在C#中存在隐式转换,但遗憾的是在F#中不起作用.
let xn s = XName.Get(s)
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用XDocumentclass和use Element方法加载XML文档以获取单个"父"元素.然后你可以调用Elements以获取所有嵌套的"property"元素:
let xd = XDocument.Load("file.xml")
let props = xd.Element(xn "parent").Elements(xn "property")
Run Code Online (Sandbox Code Playgroud)
现在,您可以搜索元素以查找具有指定属性值的一个元素.例如using Seq.tryFind(也允许你在找不到元素时处理这种情况):
let nameOpt = props |> Seq.tryFind (fun xe ->
xe.Attribute(xn "name").Value = "firstName")
Run Code Online (Sandbox Code Playgroud)
现在,值nameOpt是类型,option<XElement>因此您可以在其上进行模式匹配,以查看是否找到了元素(例如Some(el))或者是否找不到元素(None).
编辑:另一种写这个的方法是使用序列表达式,然后只取第一个元素(这不处理找不到元素的情况):
let nameEl =
seq { for el in xd.Element(xn "parent").Elements(xn "property") do
if xe.Attribute(xn "name").Value = "firstName" then yield xe }
|> Seq.head
Run Code Online (Sandbox Code Playgroud)
kvb*_*kvb 12
您不需要为此使用LINQ.这是一种方法:
open System.Xml.XPath
let getName (filename:string) =
let xpath = XPathDocument(filename).CreateNavigator()
let node = xpath.SelectSingleNode(@"parent/property[@name='firstName']")
node.Value
let files = [@"c:\root\a\file.xml"; @"c:\root\b\file.xml"]
let fileForJane = files |> List.find (fun file -> getName file = "Jane")
Run Code Online (Sandbox Code Playgroud)
此外,您可以将kvb的解决方案与(?)运算符混合使用:
let (?) (fname: string) (nodeName: string) : string =
let xpath = XPathDocument(fname).CreateNavigator()
let node = xpath.SelectSingleNode(@"parent/property[@name='"^nodeName^"']")
node.Value;;
val ( ? ) : string -> string -> string
> "i:/a.xml"?firstName;;
val it : string = "Jane"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7732 次 |
| 最近记录: |