使用F#如何访问与文档没有相同名称空间的元素?

时间:2016-12-01 21:24:24

标签: f# linq-to-xml

这是我对F#的第一次尝试,我知道我仍然需要阅读很多内容而且我会,但这些挑战有助于我理解下一部分我会更好地阅读,到目前为止我设法解决了一些首要的挑战所以请耐心等待......

xml文档如下所示:

<BuildCollection xmlns="http://schemas.datacontract.org/2004/07/BuildModels" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    ...
    <PostEvents xmlns:a="http://schemas.datacontract.org/2004/07/BuildModels.Events">
        <a:EventBase i:type="a:ExternalProcess">
            <a:Description>Structuring assemblies</a:Description>           

如何访问以&#34; a:.......&#34;?

开头的元素

在C#中,我会这样做:

foreach (var postBuildEventElement in 
    document
        .Root.Element(ns + "PostEvents")
        .Elements()
        .Where(_ => _.Name.LocalName == "EventBase"))

到目前为止在F#中我有这个:

module PostBuildInstructions

open System.Xml.Linq
open System.Linq

let xn s = XName.Get(s)

let PostBuildInstructions (xdoc: System.Xml.Linq.XDocument) =
    xdoc.Root.Elements(xn "PostEvents").Elements().Where(e => e.)

let ExecutePostBuildInstructions buildDescriptor =
    let "I need to enumerate the post build events here"

在&#34; main&#34;代码块我从这开始:(我将这个问题集中在第6行)

open Log

[<EntryPoint>]
let main argv = 
    TryLogArgs argv
    ReadPostBuildInstructions |> ExecutePostBuildInstructions
    log "Press enter to exit"
    System.Console.ReadLine() |> ignore
    0 // return an integer exit code

1 个答案:

答案 0 :(得分:4)

您对xn函数的使用不等同于C#版本中的使用。您的xn函数返回一个没有关联命名空间的名称。但是,如果您要处理名称空间中的名称,则应该生成名称。

理想情况下,您的C#版本应该是这样的:

XNamespace ns = "http://schemas.datacontract.org/2004/07/BuildModels";
XNamespace a = "http://schemas.datacontract.org/2004/07/BuildModels.Events";
var query = doc.Root
    .Elements(ns + "PostEvents")
    .Elements(a + "EventBase");

F#版本不应该有太大不同:

let ns = XNamespace.Get("http://schemas.datacontract.org/2004/07/BuildModels")
let a = XNamespace.Get("http://schemas.datacontract.org/2004/07/BuildModels.Events")
let query = doc.Root.Elements(ns + "PostEvents").Elements(a + "EventBase")

但您可能希望将它们保留为函数调用。只需确保您与函数的正确名称空间相关联。

let xn n = XName.Get(n)
let ns n = XName.Get(n, "http://schemas.datacontract.org/2004/07/BuildModels")
let a n = XName.Get(n, "http://schemas.datacontract.org/2004/07/BuildModels.Events")
let query = doc.Root.Elements(ns "PostEvents").Elements(a "EventBase")