XML文件的XSD规范可以共享共同的元素。如果我有几个共享一个公共元素的XML文件,有没有办法提取公共元素而不重复每个XML文件类型的代码?
例如:有许多XML文件通过XSD定义,具有共同的描述元素,但在其他地方有不同的内容结构。描述有子元素,如作者,日期等。当我为每个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文件的子集创建类型提供程序,并仅提取这些部分,以便代码可以更加可重用?
答案 0 :(得分: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"
这为您提供了一个带有author
子节点的描述节点,您可以为两个文档获取该节点:
description.Author