代码之家  ›  专栏  ›  技术社区  ›  user2916547

F#使用XML类型提供程序修改XML

  •  6
  • user2916547  · 技术社区  · 8 年前

    我需要处理一堆XML文档。它们的结构(即节点负载)相当复杂,但处理过程包括更改几个节点的值并以不同的名称保存文件。

    我正在寻找一种不必重构输出XML的方法,方法是显式实例化所有类型并传入所有未更改的值,而只需从输入复制它们。如果类型提供程序自动生成的类型是记录类型,我可以通过 let output = { input with changedNode = myNewValue } ,但对于类型提供程序,我必须这样做 let output = MyXml.MyRoot(input.UnchangedNode1, input.UnchangedNode2, myNewValue, input.UnchangedNode3, ...)

    1 回复  |  直到 8 年前
        1
  •  10
  •   Tomas Petricek    8 年前

    F#数据类型提供程序主要是为了在读取数据时提供方便的访问,因此它们没有编写数据的好故事(部分原因是底层的JSON表示与底层的XML表示有很大的不同)。

    XElement 类型,它碰巧是可变的。这意味着您实际上可以使用提供的类型导航到元素,然后使用底层的LINQ to XML改变值。例如:

    type X = XmlProvider<"<foos><foo a=\"1\" /><foo a=\"2\" /></foos>">
    
    // Change the 'a' attribute of all 'foo' nodes to 1234
    let doc = X.GetSample()
    for f in doc.Foos do
      f.XElement.SetAttributeValue(XName.Get "a", 1234)
    
    // Prints the modified document    
    doc.ToString()
    

    这可能并不完美-有时,您需要更改父元素(如这里所提供的 f.A 属性不是可变的),但它可能会起作用。我不知道这是否是解决一般问题的最佳方法,或者像XSLT这样的东西是否更容易——这可能取决于具体的转换。