我正在尝试从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 这样的更复杂的项目会失败。我看不出这些文件有什么问题。任何有关如何修复这些架构的帮助将不胜感激。
答案 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文件中。
这两套,你只需要使用一套。详细集:
...以及“每个命名空间的单个文件”之一:
正如我已经解释过in this post,你应该参考“单一”集。与该帖子不同,您不需要其他工具来折叠所有这些XSD文件,您将获得“单一”设置。
构建命令行遍历第二个图表,从上到下,从左到右,你应该摆脱与未定义内容相关的所有问题。
这是您在xsd.exe中遇到的一些限制,涉及对循环组引用的支持。微软说它不是(至少here和here); XSD 1.0 spec和XSD 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实现。