我有一个包含多个地址的XML架构:
<xs:element name="personal_address" maxOccurs="1">
<!-- address fields go here -->
</xs:element>
<xs:element name="business_address" maxOccurs="1">
<!-- address fields go here -->
</xs:element>
在每个地址元素中,我包含一个“美国州”枚举:
<xs:simpleType name="state">
<xs:restriction base="xs:string">
<xs:enumeration value="AL" />
<xs:enumeration value="AK" />
<xs:enumeration value="AS" />
....
<xs:enumeration value="WY" />
</xs:restriction>
</xs:simpleType>
如何编写“US State”枚举一次并在每个地址元素中重复使用它?如果这是一个n00b问题我提前道歉 - 我以前从未写过XSD。
我最初的抨击如下:
<xs:element name="business_address" maxOccurs="1">
<!-- address fields go here -->
<xs:element name="business_address_state" type="state" maxOccurs="1"></xs:element>
</xs:element>
答案 0 :(得分:5)
我认为你是在正确的轨道上。我认为它更多地与XML命名空间有关。请尝试以下方法:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/foo"
xmlns:tns="http://www.example.org/foo"
elementFormDefault="qualified">
<xs:element name="business_address">
<xs:complexType>
<xs:sequence>
<xs:element name="business_address_state"
type="tns:state" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="state">
<xs:restriction base="xs:string">
<xs:enumeration value="AL" />
<xs:enumeration value="AK" />
<xs:enumeration value="AS" />
<xs:enumeration value="WY" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
请注意,类型为 tns:州,而不仅仅是州
然后这就是你如何使用它:
<?xml version="1.0" encoding="UTF-8"?>
<business_address xmlns="http://www.example.org/foo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/foo foo.xsd ">
<business_address_state>AL</business_address_state>
</business_address>
请注意,此XML使用的默认命名空间与XSD的targetNamespace相同
答案 1 :(得分:2)
虽然命名空间有助于保持模式的组织并防止冲突, 上面的命名空间不允许重用, 它是类型作为&lt; xs:schema&gt;的直接子项的位置根 这使它成为一种全球类型。 (可以在命名空间内使用命名空间限定符,也可以在tns命名空间可见的任何地方使用tns:qualifier。)
我更喜欢按照“伊甸园”方法构建我的模式,这种模式最大化了元素和类型的重用(并且还可以促进精心制作的独特类型/元素的外部逻辑引用,例如,存储的数据字典在数据库中。
请注意,虽然“伊甸园”模式模式提供了最大程度的重用,但它也涉及最多的工作。在这篇文章的底部,我提供了博客系列中涵盖的其他模式的链接。
•伊甸园方法 http://blogs.msdn.com/skaufman/archive/2005/05/10/416269.aspx
通过全局定义所有元素来使用模块化方法,并且像Venetian Blind方法一样,所有类型定义都是全局声明的。每个元素全局定义为节点的直接子节点,其type属性可以设置为指定的复杂类型之一。
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="TargetNamespace" xmlns:TN="TargetNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="BookInformation" type="BookInformationType"/>
<xs:complexType name="BookInformationType">
<xs:sequence>
<xs:element ref="Title"/>
<xs:element ref="ISBN"/>
<xs:element ref="Publisher"/>
<xs:element ref="PeopleInvolved" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PeopleInvolvedType">
<xs:sequence>
<xs:element name="Author"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Title"/>
<xs:element name="ISBN"/>
<xs:element name="Publisher"/>
<xs:element name="PeopleInvolved" type="PeopleInvolvedType"/>
</xs:schema>
这种方法的优点是模式是可重用的。由于元素和类型都是全局定义的,因此两者都可以重用。此方法提供最大量的可重用内容。 缺点是模式很冗长。 当您创建通用库时,这将是一个合适的设计,您可以在其中对模式元素和类型的范围及其在其他模式中的使用做出任何假设,特别是在引用可扩展性和模块性方面。
由于每个不同的类型和元素都有一个全局定义,因此这些规范粒子/组件可以与数据库中的标识符一对一关联。虽然乍一看似乎是一个令人厌烦的持续手动任务来维护文本XSD粒子/组件与数据库之间的关联,但SQL Server 2005实际上可以通过语句生成规范模式组件标识符
CREATE XML SCHEMA COLLECTION
http://technet.microsoft.com/en-us/library/ms179457.aspx
相反,要从规范粒子构造架构,SQL Server 2005提供了
SELECT xml_schema_namespace function
http://technet.microsoft.com/en-us/library/ms191170.aspx
CA·非·I·CAL 与数学有关。 (等式,坐标等) “以最简单或标准的形式” http://dictionary.reference.com/browse/canonical
其他,更容易构建,但更少可恢复/更“非规范化/冗余”架构模式包括
•俄罗斯娃娃方法 http://blogs.msdn.com/skaufman/archive/2005/04/21/410486.aspx
模式只有一个全局元素 - 根元素。所有其他元素和类型逐渐深入嵌套,因为每个类型都适合上面的类型,因此给它起名称。由于此设计中的元素是在本地声明的,因此无法通过import或include语句重复使用。
• Salami Slice方法 http://blogs.msdn.com/skaufman/archive/2005/04/25/411809.aspx
所有元素都是全局定义的,但类型定义是在本地定义的。这样,其他模式可以重用这些元素。使用此方法,具有本地定义类型的全局元素提供元素内容的完整描述。这个信息'slice'是单独声明的,然后汇总在一起,也可以拼凑在一起构建其他模式。
•威尼斯盲人方法 http://blogs.msdn.com/skaufman/archive/2005/04/29/413491.aspx
与俄罗斯玩偶方法类似,它们都使用单一的全局元素。 Venetian Blind方法通过全局命名和定义所有类型定义来描述模块化方法(与Salami Slice方法相反,该方法在全局声明元素并在本地类型化)。每个全局定义的类型描述单个“板条”,并且可以由其他组件重用。此外,所有本地声明的元素都可以是命名空间限定或命名空间不合格(板条可以“打开”或“关闭”),具体取决于模式顶部的elementFormDefault属性设置。