问题描述
我想验证多态 Shape
元素,由 Type
子元素(not 属性)值区分.下面是兄弟 Circle 和 Rectangle Shape
元素.圆有一个 Radius
并且只有 1 个 Point
.矩形没有 Radius
并且有 4 个 Point
元素:
I want to validate polymorphic Shape
elements, differentiated by the Type
child element (not attribute) value. Below are sibling Circle and Rectangle Shape
elements. Circles have a Radius
and only 1 Point
. Rectangles don't have Radius
and have 4 Point
elements:
<?xml version="1.0" encoding="UTF-8" ?>
<Shapes>
<Shape>
<Type>Circle</Type>
<ID>A1234</ID>
<Label>This is round</Label>
<Radius>5.4</Radius>
<Points>
<Point>
<X>5.00</X>
<Y>2.00</Y>
</Point>
</Points>
</Shape>
<Shape>
<Type>Rectangle</Type>
<ID>B4567</ID>
<Label>This is not round</Label>
<Points>
<Point>
<X>0.00</X>
<Y>0.00</Y>
</Point>
<Point>
<X>4.00</X>
<Y>0.00</Y>
</Point>
<Point>
<X>4.00</X>
<Y>2.00</Y>
</Point>
<Point>
<X>0.00</X>
<Y>2.00</Y>
</Point>
</Points>
</Shape>
</Shapes>
这是我希望做的事情的非功能模式:
Here's a NON-functional schema along the lines of what I was hoping to do:
<xsd:simpleType name="ShapeTypeEnum">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Circle"/>
<xsd:enumeration value="Rectangle"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="ShapeBase">
<xsd:sequence>
<xsd:element name="Type" type="ShapeTypeEnum"/>
<xsd:element name="ID" type="xsd:string"/>
<xsd:element name="Label" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Shape" type="Circle">
<xsd:complexContent>
<xsd:extension base="ShapeBase">
<xsd:all>
<xsd:element name="Radius" type="xsd:decimal"/>
<xsd:element name="Points">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="1" maxOccurs="1" name="Point" type="Point"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:all>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Shape" type="Rectangle">
<xsd:complexContent>
<xsd:extension base="ShapeBase">
<xsd:all>
<xsd:element name="Points">
<xsd:complexType>
<xsd:sequence>
<xsd:element minOccurs="4" maxOccurs="4" name="Point" type="Point"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:all>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Point">
<xsd:all>
<xsd:element name="X" type="xsd:decimal"/>
<xsd:element name="Y" type="xsd:decimal"/>
</xsd:all>
</xsd:complexType>
行 和
不起作用.是否可以根据子元素(
Type
)的值来验证具有不同架构部分的同名元素?
The lines <xsd:complexType name="Shape" type="Rectangle">
and <xsd:complexType name="Shape" type="Circle">
don't work. Is it possible to validate identically named elements with different schema sections based on the value of a child Element (Type
)?
推荐答案
在 XSD 1.0 中无法做到.在 XSD 1.1 中,它可以使用断言.
In XSD 1.0, it can't be done. In XSD 1.1, it can, using assertions.
尽管即使使用断言,也不是那么容易(如果 Type
是一个属性会容易得多).您需要定义一个内容模型,该模型实际上是针对不同形状的所有不同模型的联合(在此示例中您不能使用简单的 xs:choice
,因为它会违反 UPA),然后您需要定义像
Though even using assertions, it's not that easy (it would be much easier if Type
were an attribute). You need to define a content model that's effectively a union of all the different models for different shapes (you can't use a simple xs:choice
in this example because it would violate UPA), and then you need to define assertions like
<xs:assert test="exists(radius) = (type = 'Circle')"/>
<xs:assert test="count(points) = 4 or type != 'Rectangle'"/>
Altova、Saxon 和 Xerces 支持 XSD 1.1,但 Microsoft 模式处理器不支持.
XSD 1.1 is supported in Altova, Saxon, and Xerces, but not for example by the Microsoft schema processor.
这篇关于我可以根据子 Type 元素值验证多态 XML 元素吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!