元素上下文更改时覆盖可接受的元素内容

时间:2011-12-09 08:54:58

标签: xml xsd

背景

希望定义相同类型的XML元素,但在一个上下文中作为定义,在另一个上下文中作为引用。这可能是keykeyref的情况。

问题

考虑以下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>

我想覆盖minLengthmaxLength元素,如下所示:

  <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" />引用它?

非常感谢。

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属性和/或其类型为全局。或者回到上面的复杂类型讨论。

希望它有所帮助...