从FHIR模式生成C#类

时间:2014-02-18 18:35:18

标签: c# xsd hl7-fhir

我正在尝试从FHIR项目提供的模式生成c#类: http://hl7.org/implement/standards/fhir/ 我已经下载了模式: http://hl7.org/documentcenter/public/standards/FHIR/fhir-all-xsd.zip 我有“解锁”zip文件并将xsd文件解压缩到一个文件夹中。 在尝试使用xsd.exe创建c#类时,我不断收到指示模式问题的错误。始终如一地获取 xhtml:div元素除了其他元素之外没有声明。文件 fhir-all.xsd 似乎列出了顶级对象。我能够使用简单的模式 tombstone.xsd 来使用xsd.exe,但是像 valueset.xsd或alert.xsd 这样的更复杂的项目会失败。我看不出这些文件有什么问题。任何有关如何修复这些架构的帮助将不胜感激。

4 个答案:

答案 0 :(得分:5)

从XSD生成POCO会产生不那么理想的类。由于FHIR的序列化避免了使用多态性,因此呈现选择的元素(例如Observation.value)将在XSD中表示为具有相同名称的元素集(valueNumber,valueString,valueCodeableConcept等等)。

同样,使用相同的POCO进行json序列化也很困难。

在FHIR的.NET NuGet包中,你会找到一组为FHIR资源生成的类,它们尽可能轻量级。此外,还有验证属性以验证其内容,该软件包包含json和xsd的序列化程序和解析器,以及用于调用服务器上其余操作的REST客户端。

如果您需要将解析器和序列化程序与WebAPI集成,我在此处发布了相关内容:HL7 FHIR serialisation to json in asp.net web api

答案 1 :(得分:2)

到目前为止,我已经能够生成类并反序列化提供给所述生成的原始类的许多患者* .xml样本,以及SOAP服务从原始类生成的类。

编辑xhtml1-strict.xsd来解决这个问题并不是那么简单。我使用xsd.exe尝试从文件创建类,然后使用错误消息作为起始点。经过一些实验,我想到了这个文件。它解决了div元素的问题,只要包含的HTML保持简单。我正在分享差异报告供其他人使用。数字代表行号。 (我只是因为大小限制而共享更改,我试图共享整个文件)。

XSD\xhtml1-strict.xsd(413):      <!--<xs:group ref="inline"/>-->
XSD\xhtml1-strict.xsd(441):      <!--<xs:element ref="pre"/>-->
XSD\xhtml1-strict.xsd(443):      <!--<xs:element ref="blockquote"/>-->
XSD\xhtml1-strict.xsd(462):      <!--<xs:group ref="misc"/>-->
XSD\xhtml1-strict.xsd(519):      <!--<xs:group ref="block"/>-->
XSD\xhtml1-strict.xsd(520):      <!--<xs:group ref="misc"/>-->
XSD\xhtml1-strict.xsd(539):      <!--<xs:group ref="misc"/>-->
XSD\xhtml1-strict.xsd(1349):        <!--<xs:group ref="block"/>-->
XSD\xhtml1-strict.xsd(1351):        <!--<xs:group ref="inline"/>-->
XSD\xhtml1-strict.xsd(1352):        <!--<xs:group ref="misc"/>-->
XSD\xhtml1-strict.xsd(1450):          <!--<xs:group ref="block"/>-->
XSD\xhtml1-strict.xsd(1452):          <!--<xs:group ref="misc"/>-->
XSD\xhtml1-strict.xsd(1718):          <!--<xs:group ref="block"/>-->
XSD\xhtml1-strict.xsd(1720):          <!--<xs:group ref="inline"/>-->
XSD\xhtml1-strict.xsd(1721):          <!--<xs:group ref="misc"/>-->

到目前为止,我还分享了关于所需手动编辑的笔记,以解决生成的类中的问题。

Generate entities with Xsd2Code add-in from www.codeplex.com\Xsd2Code

Use fhir-atom-single.xsd as the source XSD
Use Parms:
    Serilization.GenerateXMLAttributes = true
    Code.Namespace = Hl7.Fhir.Validation.SchematronOutput
    Collection.CollectionObjectType=Array

!!! Do not open Schema in Designer, or classes will change.

Manual updates:

    public partial class boolean : Element
    ...
        [System.Xml.Serialization.XmlAttributeAttribute("value")]
        public bool Value
        {


    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false, Namespace = "http://www.w3.org/1999/xhtml")]
    public partial class div : Flow


    Refactor:
    public partial class FeedType
    to
    public partial class feed

答案 2 :(得分:1)

首先,您需要了解FHIR XSD文件描述了两个相同的XML Schema集:一个“详细”的XML Schema集,它维护标准的逻辑包装(它使用了大量&lt; xsd:include&gt;),和“单一”一个,出于互操作性的原因,它不使用include指令,即所有针对特定命名空间的内容都放在一个XSD文件中。

这两套,你只需要使用一套。详细集:

enter image description here

...以及“每个命名空间的单个文件”之一:

enter image description here

正如我已经解释过in this post,你应该参考“单一”集。与该帖子不同,您不需要其他工具来折叠所有这些XSD文件,您将获得“单一”设置。

构建命令行遍历第二个图表,从上到下,从左到右,你应该摆脱与未定义内容相关的所有问题。

这是您在xsd.exe中遇到的一些限制,涉及对循环组引用的支持。微软说它不是(至少herehere); XSD 1.0 specXSD 1.1 spec都读取了

  

没有循环组。也就是说,在a的{粒子}内   在{term}为组的任何深度都没有粒子   本身。

上面对xsd.exe使用的解释会导致问题。 xhtml1-strict.xsd文件充满了“循环组”依赖关系。你将无法使用xsd.exe 来逃避这些错误,除非你修复了那个文件(我们为客户端做了一次)或修改了对FHIR库所在行的任何xhtml内容的引用处理HTML标记。后一种方法与那种不应该为HTML标记生成代码绑定的视图更加一致,因为它具有混合的内容性质,这使得它在所有代码中都没用(至少没有可能的往返,也没有正确读取文本节点)我能想到的绑定技术,包括.NET的序列化。

鉴于@ GrahameGrieve的第二条评论,我应该明确指出.NET内置的XSD处理器正确验证了XHTML架构。所以这不是.NET XSD处理器问题,而是xsd.exe所依赖的.NET其他部分的问题(更具体地说,它是xsd.exe所做的外部调用,XmlSchemaImporter.ImportTypeMapping它悲惨地失败了)

这个我会责怪规范不清楚,以避免这种混乱,在我看来,部分部分归咎于主流产品行为不端。

答案 3 :(得分:0)

感谢Petru,命令是: xsd.exe fhir-atom-single.xsd tombstone.xsd fhir-single.xsd opensearch.xsd opensearchscore.xsd xmldsig-core-schema.xsd xhtml1-strict.xsd xml.xsd / c

并且在从xhtml1-strict.xsd注释循环引用之后创建类

然而,正如Ewout指出这不是一个完整的修复,因为模式本身被设计为对POCO类不友好。

在患者类中这个元素:

  <xs:choice minOccurs="0" maxOccurs="1" >
    <xs:annotation>
      <xs:documentation>Indicates if the individual is deceased or not.</xs:documentation>
    </xs:annotation>
    <xs:element name="deceasedBoolean" type="boolean"/>
    <xs:element name="deceasedDateTime" type="dateTime"/>
  </xs:choice>

收率:

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("deceasedBoolean", typeof(boolean))]
[System.Xml.Serialization.XmlElementAttribute("deceasedDateTime", typeof(dateTime))]
public Element Item {
    get {
        return this.itemField;
    }
    set {
        this.itemField = value;
    }
}

我已在FHIR评论中报告了这些调查结果,并希望能够解决这些问题。 与此同时,我可以继续我的初衷。使用这些定义的API的SOAP实现。