问题描述
我如何为此 XML-1 编写 XSD(简化示例):
<?xml version="1.0" encoding="utf-8"?>
<user>
<username>Albert Einstein</username>
<!-- no wrapper element for address -->
<street>Main Street</street>
<city>Ghost Town</city>
<state>Up State</state>
</user>
而不是更合乎逻辑的 XML-2:
<?xml version="1.0" encoding="utf-8"?>
<user>
<username>Albert Einstein</username>
<!-- with wrapper element for address -->
<address>
<street>Main Street</street>
<city>Ghost Town</city>
<state>Up State</state>
</address>
</user>
其中 username
代表不属于地址数据库表的一部分的所有字段,这是一个我不能更改以包含更多字段的表,
对于 address
这样的 XSD 字段使用某种记录类型:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="user" type="user" />
<!-- =========================================== -->
<xsd:complexType name="user">
<xsd:sequence>
<!-- username stands for all non-address fields -->
<xsd:element name="username" type="xsd:string" />
<!-- wrapper element for the address fields -->
<xsd:element name="address" type="address_Type" />
</xsd:sequence>
</xsd:complexType>
<!-- =========================================== -->
<xsd:complexType name="address_Type">
<!-- the columns of the database table for addresses -->
<xsd:sequence>
<xsd:element name="street" type="xsd:string" />
<xsd:element name="city" type="xsd:string" />
<xsd:element name="state" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
使用 Visual Studio 中的工具,我验证了 XML-2 可以使用 XSD 进行验证,但 XML-1 没有。如何改进 XSD 中的“问题线”?显然,您不能在 XSD 中写入没有名称的元素:
<xsd:element type="address_type" />
我需要为 complexType
字段包含 address
而不包含封闭
<address>
标签。
这个问题的原因是这个 XSD 将有助于在 Visual Studio sdk 中使用 xsd.exe 为数据库表 address
创建 C# 类。
我将不得不处理许多不同格式的 XML,其中大多数在地址包装元素中都有地址数据。扩展 XSD 以验证这些 XML 很容易。问题在于带有地址数据的 XML 没有包装元素,这似乎无法使用具有 complexType Address_Type 的 XSD 进行验证。除非有比我更聪明的人看到了解决方案。
由于 complexType 和数据库表结构的关系,我不能只将 username 字段添加到 complexType 中。用户名实际上代表不在地址表中的所有字段。
我愿意接受所有建议。即使做了很多 XSD 的东西,我仍然觉得自己是个初学者,我什至不确定是否需要使用 xsd:sequence。
解决方法
更新:已在此处创建了解决@Roland 精炼要求的新问答:
原始的、过时的答案和更新如下......
如果您不想要一个包装器 address
元素,您可以简单地不定义一个,并将其内容模型直接放在 user
的内容模型中:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="user" type="user" />
<xsd:complexType name="user">
<xsd:sequence>
<xsd:element name="username" type="xsd:string" />
<xsd:element name="street" type="xsd:string" />
<xsd:element name="city" type="xsd:string" />
<xsd:element name="state" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
根据您的评论,您不想执行上述操作;您想重用 address_Type
中的元素。
没有直接的方式来表达您想要什么,但您可以让 user
复杂类型扩展 address_Type
复杂类型。这将允许您将 username
元素添加到已经出现在 address_type
中的那些元素中(尽管以这种方式扩展地址会显得很不自然)。
要更自然地重用部分内容模型,请考虑使用 xs:group
。有关示例,请参阅