F# XML类型提供程序的常见元素

3

XSD规范适用于XML文件可以共享公共元素。如果我有几个XML文件共享一个公共元素,是否有一种方法可以提取公共元素而不必为每个XML文件类型重复代码?

例如:有许多通过XSD定义的XML文件,具有共同的描述元素,但其他地方具有不同的内容结构。描述具有诸如作者、日期等子元素。当我为每个XML文件创建类型提供程序时,类型是不同的,因此如果我只想从每个文件中提取描述部分,则必须将代码复制粘贴到每个类型中。

XML文件1:

<root>
  <description >
     <author> Me </author>     
  </description>
  <element > Data </element>
  <otherelement> Data </otherelement>
</root>

XML文件2:

<root2>
  <description >
     <author> Me </author>     
  </description>
  <elem > Data </elem>
  <diffelem> Data </diffelem >
</root2>

需要的代码类似于:
type File1 = XmlProvider<""".\file1.xml""">
type File2 = XmlProvider<""".\file2.xml""">

let descript1 = 
    File1.GetSample().description.author   
let descript2 = 
    File2.GetSample().description.author    //duplicated code

这种情况下很简单,但是如果描述更长、xml文件类型更多,则会变得更为复杂。

有没有办法解决这个问题?可以为XML文件的子集创建类型提供程序,仅提取那些部分以使代码更具可重用性吗?

1个回答

4
XML类型提供者最适合处理输入相对规律的情况。因此,如果您需要处理多个不同的模式,使用标准的XML工具(如XDocument)可能更好。
话虽如此,您可以使用一些技巧使您的场景更加顺畅。首先,您可以指定一个示例列表。为此,请创建一个具有任意根和两个示例的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<samples>
  <root>
    <description><author> Me </author></description>
    <element > Data </element>
    <otherelement> Data </otherelement>
  </root>
  <root2>
    <description ><author> Me </author></description>
    <elem > Data </elem>
    <diffelem> Data </diffelem >
  </root2>
</samples>

现在你可以创建 XML 类型提供程序,并告诉它你的示例文件是一个列表 (SampleIsList=true),并且它应该使用全局解析 (即所有名为 description 的元素都将被视为同一类型的值)。
type X = XmlProvider<"C:/temp/sample1.xml", SampleIsList=true, Global=true>

现在,你有不同命名的根节点,这使情况更加棘手,但你现在可以编写代码来从一个或另一个根节点获取<description>元素。
let i = X.Load("...")

let description = 
  match i.Root, i.Root2 with
  | Some r1, _ -> r1.Description
  | _, Some r2 -> r2.Description
  | _ -> failwith "Missing"

这将为您提供一个具有作者子节点的描述节点,您可以在两个文档中获取该节点:
description.Author

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接