我需要处理一堆XML文档。它们的结构非常复杂(即节点的负载),但处理包括更改几个节点的值并以不同的名称保存文件。
我正在寻找一种方法来实现这一点,而无需通过显式实例化所有类型并传递所有未更改的值来重构输出XML,而只需通过从输入中复制它们。如果类型提供程序自动生成的类型是记录类型,我可以简单地通过let output = { input with changedNode = myNewValue }
创建输出,但是使用类型提供程序我必须let output = MyXml.MyRoot(input.UnchangedNode1, input.UnchangedNode2, myNewValue, input.UnchangedNode3, ...)
。由于我在某些嵌套节点中更改了值,因此我会有相当多的毛茸茸来传递它。
答案 0 :(得分:6)
F#数据类型提供程序主要用于在读取数据时提供方便的访问,因此它们没有很好的编写数据的故事(部分原因是问题是底层JSON表示与底层XML表示完全不同) )。
对于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之类的东西是否更容易 - 它可能取决于具体的转换。