【问题标题】:XSD: Adding attributes to strongly-typed "simple" elementsXSD:向强类型“简单”元素添加属性
【发布时间】:2009-03-17 06:11:37
【问题描述】:

是否有一些明智的方法来让元素具有强类型的简单类型和属性?

好的,我有一个 XSD 架构,其中包含一百万个(呃,一百个)元素,可能看起来像这样:

<xsd:element name="DocumentDescription" type="xsd:string" />
<xsd:element name="DocumentDateTime" type="xsd:dateTime" />
<xsd:element name="DocumentSize" type="xsd:int" />

那是花花公子。但是,我真的希望所有这些元素也有一些共同的属性,比如“格式”和“isVisible”。即有这样的架构:

<DocumentDescription isVisible="true">doc description</DocumentDescription>
<DocumentDateTime format="dd/mm/yyyy" isVisible="true">1/1/2008</DocumentDescription>
<DocumentSize format="0.00 KB" isVisible="false">5403</DocumentSize>

我可以手动完成,非常可怕的是,在生成 XSD 时将所有此类属性添加到 XSD,如下所示:

<xsd:element name="DocumentDescription" />
  <xsd:complexType>
    <xsd:simpleContent>
      <xsd:extension base="xsd:string">
        <xsd:attribute name="format" type="xsd:string" />
        <xsd:attribute name="isVisible" type="xsd:boolean" />
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>
<xsd:element name="DocumentDateTime" />
   ... etc

...但在理想世界中,我宁愿将其定义为 complexType:

<xsd:complexType name="customType">
  <xsd:complexContent>
    <xsd:extension base="???">
      <xsd:attribute name="format" type="xsd:string" />
      <xsd:attribute name="isVisible" type="xsd:boolean" />

...这意味着我可以这样做:

<xsd:element name="DocumentDescription" type="customType" baseType="xsd:string" />
<xsd:element name="DocumentDateTime" type="customType" baseType="xsd:dateTime" />
<xsd:element name="DocumentSize" type="customType" baseType="xsd:int" />

我的“理想世界”代码的问题在于:

a) 我没有有效的&lt;xsd:extension base-"???">,因为我真的不在乎我在扩展什么;我想扩展所有类型。似乎“xsd:anyType”是合适的,但是元素变成了弱类型容器不是吗?

b) 我不能再在&lt;xsd:element> 上指定简单类型,因为现在类型是我定义的复杂“customType”。因此,我放在那里的想象中的“baseType”属性......

那么我可以以一种不笨拙的方式为简单类型添加属性吗?或者我是否需要定义十几个除了它们扩展的简单类型之外都相同的复杂类型?

强类型元素不仅可以更合理地描述数据,而且当我将它们用于 Excel 中的 XML 映射时(这就是这些东西背后的全部目的),强类型意味着 Excel 根据正确设置单元格格式关于类型。

我可能看错了!任何建议表示赞赏。

【问题讨论】:

  • 我取消了一个版本,该版本包括用内置简单类型 (W3C wording) 重命名所有出现的strongly-type。这样的措辞会帮助我找到你的问题。现在我不确定编辑是否值得,我很高兴我的评论包括这个措辞,所以我以后可以再次找到你的问题。

标签: xml excel xsd


【解决方案1】:

尚不清楚您认为手动解决方案的哪个方面很糟糕;如果只是因为它们需要扩展 n 个不同的基本类型而必须定义 n 个不同的类型,那么你就被困住了。

如果您的想法是必须为formatisVisible 属性设置n 个不同的声明,那么您可能会发现使用命名属性组来保存这些定义并不那么可怕:

<xs:attributeGroup name="globals">
  <xs:attribute name="format" type="xs:string"/>
  <xs:attribute name="isVisible" type="xs:boolean"/>
</xs:attributeGroup>

您需要的各种复杂类型的声明仍然是重复的,但现在稍微不那么冗长了:

<xs:complexType name="string">
  <xs:simpleContent>
    <xs:extension base="xs:string">
      <xs:attributeGroup ref="my:globals"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>
<xs:complexType name="dateTime">
  <xs:simpleContent>
    <xs:extension base="xs:dateTime">
      <xs:attributeGroup ref="my:globals"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>
<xs:complexType name="int">
  <xs:simpleContent>
    <xs:extension base="xs:int">
      <xs:attributeGroup ref="my:globals"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>

您的元素声明现在比您的“理想”情况稍微简单一些:

<xs:element name="DocumentDescription" type="my:string" />
<xs:element name="DocumentDateTime" type="my:dateTime" />
<xs:element name="DocumentSize" type="my:int" />

【讨论】:

  • 在 XSD 1.1 中有一个名为 defaultAttributes 的模式属性,它将属性组应用于每个 complexType,除非在该 complexType 中将 defaultAttributesApply 设置为 false。这不适用于 simpleTypes,但是使用您的出色方法,您必须为每个 complexType 声明少写两行,因为扩展名可以是自封闭标签&lt;xs:extension base="xs:string"/&gt;
【解决方案2】:

[quote] 可以手动完成,而且很可怕,通过 将所有此类属性添加到 XSD 当我生成它时,就像 这个:[/quote]

恐怕这是您唯一的“正确”、兼容 XSD 架构的方式。

XSD 有时会让作者感到费解 - 但它有助于保证安全:-)

马克

【讨论】:

  • 该死!非常感谢。不过,考虑到元素的数量,我可能会先尝试十几个相同的扩展复杂类型,尽管它至少会使 XSD 更小,尽管很丑!
  • @Gavin 如果您总是添加相同的一组属性,值得看看C. M. Sperberg-McQueenattributeGroup 建议
【解决方案3】:

XSD 的目的是描述您的数据。 XSD 的 type 属性的目的是描述或定义一个元素。您要做的是更改元素的定义。如果您要更改描述,请更改类型。你试图做的就像给一个想法装上轮子。 “但我想要推动我的思想!” “对不起,没办法。”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    相关资源
    最近更新 更多