【问题标题】:XSD attribute for "some" elements“一些”元素的 XSD 属性
【发布时间】:2012-09-09 19:42:06
【问题描述】:

这将是一个很长的帖子,谢谢你的准备:-) 这个问题来自这篇文章的一个更高层次的“观点”:

Storing meta information to class properties

我们有一个 XSD,我们将从 (C#/Java) 生成类。所以问题分为两个不同的部分:在 XSD 中定义它,然后从中创建数据模型。

我们希望在复杂类型中包含一些元素来携带元信息,但只是在 XSD 中的某些 x 路径中。这意味着当一个类型被重用为另一个复杂类型中的元素时,我们想告诉用户它是否与某些东西“相关”(我在另一篇文章中称其为安全相关)。相关性在几个层次上表示。 (这种解释当然也适用于 C#/Java 中的数据模型)

XSD 类型示例:

<xs:complexType name="Core">
  <xs:sequence>
    <xs:element name="No" type="xs:int" />
  </xs:sequence>
</xs:complexType>

<xs:complexType name="ComplexA">
  <xs:sequence>
    <xs:element name="Info" type="Core" />
  </xs:sequence>
</xs:complexType>

<xs:complexType name="ComplexB">
  <xs:sequence>
    <xs:element name="Info" type="Core" />
  </xs:sequence>
</xs:complexType>

Core 类型有一个属性“No”。此属性可能与其他类型相关。例如,它应该是 ComplexA.Info 类型中的“relevant-level-1”,而在 ComplexB.Info 中不是。

我们想出了两种不同的方法来实现这一点:

1:在类型级别引入属性:

<xs:complexType name="ComplexA">
  <xs:sequence>
    <xs:element name="Info" type="Core" />
  </xs:sequence>
  <xs:attribute name="Relevance.Info.No" type="RelevanceType" fixed="Relevance1"/>
</xs:complexType>

<xs:simpleType name="RelevanceType">
  <xs:restriction base="xs:string">
    <xs:enumeration value="Relevance1" />
    <!-- Some more relevance values -->
  </xs:restriction>
</xs:simpleType>

属性“Relevance.Info.No”基本上告诉成员“Info”中的属性“No”具有关联类型“Relevance1”。这种方法显然有一些缺点。类生成非常复杂,因为我们必须手动处理这些属性信息。解决方案在开头提到的线程中发布。

2:为每个具有相关级别的属性引入另一种复杂类型:

这将解决这种“元数据”附加到属性的方式,但显然会在 XSD 和 C#/Java 上为类型中的每个相关级别组合生成 很多 类。

您可以想象,在 C# 和 Java 端创建数据模型的问题与 XSD 中的问题非常相似。最好的方法是让 XSD 准备好自动创建 java 类 (JaxB) 和 C# 类 (XGen),而无需对生成的代码进行任何其他操作(我现在正在这样做)。

您认为还有其他实现这一目标的可能性吗?

感谢任何帮助!

【问题讨论】:

  • 属性在给定上下文中的相关性是实例的函数,还是纯粹是类系统的函数?从您的示例中使用 fixed 值来看,我想它在实例中不会有所不同;如果是这样,我想知道element 引用上的扩展属性是否足够? `
  • @C.M.Sperberg-McQueen:相关性可以从模型路径到模型路径有所不同,它只是针对该特定类型层次结构的所有实例固定。关于属性扩展:无论哪种方式,这只会简化语法,对吗?

标签: c# java xsd code-generation metadata


【解决方案1】:

在这种情况下,我相信您需要使用继承。如果您再定义一个名为 CoreBase 的类型,并且如果您在 Core 中继承此类型

您可以在ComplexA 中使用Core,也可以在ComplexB 中使用CoreBase

<xs:complexType name="CoreBase">
  <xs:sequence>
    ... some attributes or how ever you wish
  </xs:sequence>
</xs:complexType>

<complexType name="Core">
    <complexContent>
        <extension base="CoreBase">
            <sequence>
                <xs:element name="No" type="xs:int" />
            </sequence>
        </extension>
    </complexContent>
</complexType>

<xs:complexType name="ComplexA">
  <xs:sequence>
    <xs:element name="Info" type="Core" />
  </xs:sequence>
</xs:complexType>

<xs:complexType name="ComplexB">
    <xs:sequence>
        <xs:element name="Info" type="CoreBase" />
    </xs:sequence>
</xs:complexType>

请查看xml架构中的继承链接Xsd and inheritance

【讨论】:

  • 感谢您的回复,但正如我所说,这将创建很多“基类”,因为可以有多种属性组合。现在我不认为使用 XSD 技术可以解决这个问题。只是不能这样使用。
【解决方案2】:

正如我在对答案的评论中所说,我认为没有一个干净的解决方案。也许 XML 不适合这样使用。
但我仍然对其他解决方案感兴趣......

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多