F#XML类型提供程序公共元素 [英] F# XML Type Provider Common Elements

查看:61
本文介绍了F#XML类型提供程序公共元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

XSD specifications for XML files can share common elements. If I have several XML files that share a common element, is there a way to extract the common element without repeating the code for each XML file type?

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

For example: There are a number of XML files defined via XSD, with a common description element, but different content structures elsewhere. The description has subelements with things like author, date, etc. When I create a type provider for each of the XML files, the types are different, so if I only want to extract the description section out of each, the code has to be copy pasted for each of the types.

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文件类型.

Simple in this case, but gets more involved with a longer description and more xml file types.

有没有解决的办法?是否可以为XML文件的子集创建类型提供程序,而仅提取这些部分,以便使代码更可重用?

Is there a way around this? Can a type provider be created for a subset of an XML file and only extract those parts so the code can be more reusable?

推荐答案

在您的输入相当规则的情况下,XML类型提供程序效果最好.因此,如果您需要处理多个不同的模式,则最好使用标准的XML工具(如XDocument).

The XML type provider works the best in the case when your inputs are fairly regular. So, if you need to process multiple different schemas, it might be better to use the standard XML tools (like XDocument).

也就是说,您可以使用一些技巧来使您的场景变得更好.首先,您可以指定样本的列表.为此,只需创建一个具有某些(任意)根目录和两个示例的XML文件:

That said, you can use a few tricks that make your scenario nicer. First, you can specify a list of samples. To do that, just create a XML file that has some (any) root and both of your samples:

<?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的元素都将被视为相同类型的值):

Now you can create XML type provider and tell it that your sample file is a list (SampleIsList=true) and that it should use global resolution (meaning that all elements named description will be treated as values of the same type):

type X = XmlProvider<"C:/temp/sample1.xml", SampleIsList=true, Global=true>

现在,您有了不同名称的根,这使情况变得更加棘手,但是现在您可以编写代码,以从一个或另一个根获取<description>元素:

Now, you have differently named roots, which makes the situation trickier, but you can now write code that gets the <description> element from one or the other root:

let i = X.Load("...")

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

这为您提供了一个带有author子节点的描述节点,您可以为两个文档获得该子节点:

This gives you a description node with author sub node that you can get for both of your documents:

description.Author

这篇关于F#XML类型提供程序公共元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆