希望定义相同类型的XML元素,但在一个上下文中作为定义,在另一个上下文中作为引用。这可能是key
和keyref
的情况。
考虑以下XML:
<recipe>
<equipment>
<bakeware>
<object id="1">pan</object>
</bakeware>
<cookware>
<object id="2">pot</object>
</cookware>
</equipment>
<directions label="dough">
<step action="roll" time="3">dough on <object id="1" /> until thin</step>
</directions>
</recipe>
在equipment
元素的任何子元素中,object
元素必须同时包含id
和文本值。在任何step
元素中,object
元素都可以显示,但其id
属性必须引用现有的object
,并且可能不包含文本节点。
我正在解决此问题的方法是为object
创建两个定义:(1)objectType
; (2)objectDefType
。这可能是一个错误(似乎应该可以进行继承)。
这是我到目前为止所做的:
<xsd:simpleType name="rString">
<xsd:restriction base="xsd:normalizedString">
<xsd:minLength value="1" />
<xsd:maxLength value="64" />
<xsd:whiteSpace value="collapse" />
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="objectDefType">
<xsd:simpleContent>
<xsd:extension base="rString">
<xsd:attribute name="id" type="rId" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
我想覆盖minLength
和maxLength
元素,如下所示:
<xsd:complexType name="objectType">
<xsd:simpleContent>
<xsd:extension base="rString">
<xsd:attribute name="id" type="rId" use="required" />
<xsd:minLength value="0" />
<xsd:maxLength value="0" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
这会导致错误:
内容无效。预期是(注释?,((attribute | attributeGroup)*,anyAttribute?))。
我尝试了几种方法来定义此项,包括将其更改为complexContent
,但每次尝试都会导致不同的错误。
使用<object id="1">pan</object>
定义对象的XSD是什么,并通过文档中其他位置的键<object id="1" />
引用它?
非常感谢。
答案 0 :(得分:1)
要修复XSD错误,这就是修正后的定义的样子 - 它基本上定义了一个包含emtpy内容的元素。
<xsd:complexType name="objectType">
<xsd:attribute name="id" type="rId" use="required"/>
</xsd:complexType>
实际上,这是唯一的方法。尝试从结构角度(具有objectType restrict objectDefType)起作用的其他组合将无法从“派生”方面的值视角工作:不能使它们小于父级的值。
至于另一部分,我会尝试解释我的思考过程,让你根据你的特定约束来改进它。
我开始使用XML并从中生成虚拟XSD。以下是它的结果,它可以工作(它验证特定的XML实例):
<?xml version="1.0" encoding="utf-16"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="recipe">
<xs:complexType>
<xs:sequence>
<xs:element name="equipment">
<xs:complexType>
<xs:sequence>
<xs:element name="bakeware">
<xs:complexType>
<xs:sequence>
<xs:element name="object">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:unsignedByte" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="cookware">
<xs:complexType>
<xs:sequence>
<xs:element name="object">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:unsignedByte" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="directions">
<xs:complexType>
<xs:sequence>
<xs:element name="step">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="object">
<xs:complexType>
<xs:attribute name="id" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="action" type="xs:string" use="required" />
<xs:attribute name="time" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="label" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
从这一点来看,你会注意到的第一件事就是使用这种创作风格,称为俄罗斯玩偶,因为一切都是嵌套的,你将有两个本地的,因此完全独立的对象标签定义。这可能是您的解决方案的基础,现在取决于您希望重用XSD内容的内容和方式。
拥有“上下文”的最简单方法是使元素在您的上下文中是本地的。要重用部件,一种方法可能是使id属性和/或其类型为全局。或者回到上面的复杂类型讨论。
希望它有所帮助...