我有一种情况,XML文件中的元素在XSD中可以有两种不同的类型。
我想要做的是首先将输入的值验证为更严格的类型(如果它是填写表单的人),如果没有通过,请将其验证为较严格的类型(如果是填写表单的组织,否则如果根本不验证则验证失败。
所以基本上就是这样:
<xsd:complexType name="ForminfoType"> `
<xsd:sequence>
<xsd:element name="formname" type="xsd:string" />
<xsd:element name="timestamp" type="xsd:dateTime" />
<xsd:element name="sender" type="PersonType" minOccurs="0" />
<xsd:element name="receiver" type="OrganizationType" minOccurs="0" />
<xsd:element name="signature" type="xsd:string" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
PersonType声明的内容基本上是根据特定模式构造的12位数字。组织类型声明的基本上只是一个10位数字。
所以我在逻辑上想做的就是把它放在:
<xsd:element name="sender" type="OrganizationType" minOccurs="0" />
进入序列,但不能有两个具有相同名称和不同类型的元素。所以我认为我必须以其他方式解决它。
我发现的是: http://xsd.stylusstudio.com/2007Oct/post05003.htm
这几乎是我想要做的,但我不确定这是可能的。 有没有人对如何解决这个问题有任何进一步的想法?
提前致谢。
答案 0 :(得分:12)
不,你真的不能这样做。您有一个选项可以创建“PersonOrOrgSender”复杂类型:
<xsd:complexType name="PersonOrOrgType">
<xsd:choice>
<xsd:element minOccurs="0" name="PersonSender" type="PersonType" />
<xsd:element minOccurs="0" name="OrgSender" type="OrganizationType" />
</xsd:choice>
</xsd:complexType>
然后让“发件人”成为该类型的实例:
<xsd:element name="sender" type="PersonOrOrgType" minOccurs="0" />
但是你会得到这样的XML数据:
<FormInfo>
<formname>string</formname>
<sender>
<OrgSender>
<Name>string</Name>
</OrgSender>
</sender>
...
</FormInfo>
或
<FormInfo>
<formname>string</formname>
<sender>
<PersonSender>
<Name>string</Name>
</PersonSender>
</sender>
...
</FormInfo>
你不能让一个标签(例如“发送者”)在一个案例中成为一件事而在另一个案例中成为另一个 - 一个标签必须具有一个明确定义的类型,并且一次又一次具有该类型。
马克
答案 1 :(得分:2)
鉴于您对@mark_s提供的解决方案存在问题,您有以下几种选择:
sender
的两种类型创建两个单独的XSD。在触发验证的代码中,按顺序运行它们(即人员然后组织)。这样做的另一个好处是,您的代码将知道哪些验证通过(并且可以根据该知识做出选择)。将选项在XSD中向上移动一级。在ForminfoType
内,添加一个包含两个序列的选择节点(一个人,一个组织)。我没有验证,但粗略地说:
<xsd:complexType name="ForminfoType">
<xsd:choice>
<xsd:sequence> <!-- person -->
<xsd:element name="formname" type="xsd:string" />
<xsd:element name="timestamp" type="xsd:dateTime" />
<xsd:element name="sender" type="PersonType" minOccurs="0" />
<xsd:element name="receiver" type="OrganizationType" minOccurs="0" />
<xsd:element name="signature" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:sequence> <!-- organization -->
<xsd:element name="formname" type="xsd:string" />
<xsd:element name="timestamp" type="xsd:dateTime" />
<xsd:element name="sender" type="OrganizationType" minOccurs="0" />
<xsd:element name="receiver" type="OrganizationType" minOccurs="0" />
<xsd:element name="signature" type="xsd:string" minOccurs="0" />
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
答案 2 :(得分:0)
虽然是很旧的帖子,但这可能对某人有所帮助。
您可以通过子类型化然后在 XML 中使用 xsi:type 属性来实现这一点。您可以参考以下链接了解详细信息和示例。