【问题标题】:How to utilize complexType without wrapper element in XSD? [duplicate]如何在 XSD 中使用没有包装器元素的 complexType? [复制]
【发布时间】:2021-02-19 18:34:54
【问题描述】:

如何为此 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" />

我需要为 address 字段添加 complexType 而不包含封闭

<address> 

标签。

这个问题的原因是这个 XSD 将有助于使用 Visual Studio sdk 中的 xsd.exe 为数据库表 address 创建一个 C# 类。

我将不得不处理许多不同格式的 XML,其中大多数都在地址包装元素中包含地址数据。扩展 XSD 以验证这些 XML 很容易。问题在于带有地址数据的 XML 没有包装器元素,这似乎无法使用带有 complexType Address_Type 的 XSD 进行验证。除非比我更聪明的人找到解决方案。

由于 complexType 和数据库表结构之间的关系,我不能只在 complexType 中添加用户名字段。用户名实际上代表所有不在地址表中的字段。

我愿意接受所有建议。即使做了很多 XSD 的事情,我仍然觉得自己像个初学者,我什至不确定是否需要使用 xsd:sequence。

【问题讨论】:

    标签: xml xsd deserialization xsd-validation xml-validation


    【解决方案1】:

    更新:已在此处创建了解决 @Roland 的细化要求的新 Q/A:

    以下是原始的、过时的答案和更新......


    如果您不想要包装器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。例如,请参阅

    【讨论】:

    • 您的答案没有将 complexType 用于地址字段。问题是:如何在 XSD 中引用 complexType 的地址而不需要 xml 中的
      标记?我应该更改这个问题的标题吗?我不确定这个问题的最佳术语。而且,实际上,不是我不想要 wrapper 元素,而是其他人懒得应用 wrapper 元素。使用 wrapper 元素使事情变得容易得多。问题是如何在没有包装元素的情况下应对? xsd 将具有其他带有包装元素的 xml 的 complexType。
    • 已更新答案以解决您的后续问题。
    • 感谢更新,但用户名代表所有不在地址类型中的字段,代表一些数据库表的正式表示。我需要将地址字段集 NEXT 处理为非地址字段。我不能只用额外的用户名字段更改数据库表地址。如果没有包装器元素,Address_Type 的 complexType 似乎是不可能的。另一方面,这里有很多聪明人可能还有更好的解决方案。
    • 我相信xs:complexType 扩展和xs:group 建议都不依赖于username 作为您希望补充的唯一元素。你读过我建议的关于xs:group 的问答吗?我还添加了另一个关于 xs:complexType 扩展的 Q/A 链接。
    • 我确实从链接的问题中学到了很多东西,因此得到了支持。在我发布了一个更好的问题并在那里得到更清晰的答案后,请参阅:stackoverflow.com/q/66286743/1845672,我明白这个答案确实有解决方案,所以我接受了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 2019-07-28
    • 2013-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多