如何在 XSD 中使用没有包装元素的 complexType?

问题描述

我如何为此 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。有关示例,请参阅

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...