且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在 XSD 中使用 xsi:type 限制 XML 元素的值?

更新时间:2023-09-27 16:23:22

要在 XML 文档中使用 xsi:type:

  1. 声明 xsi 命名空间前缀,通常在根元素上:

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  2. 声明xs(或xsd)命名空间前缀,通常在根元素上:

    xmlns:xs="http://www.w3.org/2001/XMLSchema"

  3. 向您希望约束的元素添加任何 XSD 类型:

    xsi:type="xs:boolean"

这些更改直接在您的 XML 文档中进行.您不必对 XSD 进行任何更改.但是,所选类型必须从 XSD 为给定元素提供的类型有效派生.

相关的 W3C 参考

来自

I would like to validate text values of an element based on attribute value. For example

<Device xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Parameter xsi:type="xsd:unsignedInt">-100</Parameter>
  <Parameter xsi:type="xsd:boolean"></Parameter>
  <Parameter>hello</Parameter>
</Device>

Both the above should fail. For boolean, anything shouldn't be accepted except "true" or "false" (even empty string)

My xml is much more complex with lot of Object and Parameter nodes and this is my xsd which is validating all those nodes recursively

    <xs:complexType name="deviceType">
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element ref="Object"/>
                    <xs:element ref="Parameter"/>
            </xs:choice>
    </xs:complexType>

    <xs:complexType name="objType">
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element ref="Object"/>
                    <xs:element ref="Parameter"/>
            </xs:choice>
            <!-- Add all valid attributes for 'Object' type here -->
            <xs:attribute name="Id" use="required"/>
            <xs:attribute name="Flag" use="required"/>
            <xs:anyAttribute processContents="lax"/>
    </xs:complexType>

    <xs:complexType name="paramType" mixed="true">
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element ref="Object"/>
                    <xs:element ref="Parameter"/>
            </xs:choice>
            <xs:attribute name="Id" use="required"/>
            <xs:attribute name="Flag" use="required"/>
            <xs:anyAttribute processContents="lax"/>
    </xs:complexType>

But I'm facing this error.

Type 'xsd:unsignedInt' is not validly derived from the type definition, 'paramType', of element 'Parameter'.
Type 'xsd:unsignedInt' is not validly derived from the type definition, 'paramType', of element 'Parameter'.

How can I fix this?

To use xsi:type in your XML document:

  1. Declare the xsi namespace prefix, usually on the root element:

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    

  2. Declare the xs (or xsd) namespace prefix, usually on the root element:

    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    

  3. Add any XSD type to the element you wish to constrain:

    xsi:type="xs:boolean"
    

These changes are made directly in your XML document. You do not have to make any changes to your XSD. However, the chosen type must be validly derived from the type provided by the XSD for the given element.


Relevant W3C References

From XML Schema Part 1: Structures Second Edition...

2.6.1 xsi:type

The Simple Type Definition (§2.2.1.2) or Complex Type Definition (§2.2.1.3) used in ·validation· of an element is usually determined by reference to the appropriate schema components. An element information item in an instance may, however, explicitly assert its type using the attribute xsi:type. The value of this attribute is a ·QName·; see QName Interpretation (§3.15.3) for the means by which the ·QName· is associated with a type definition.

[...]

Validation Rule: Element Locally Valid (Element)

4.3 The ·local type definition· must be validly derived from the {type definition} given the union of the {disallowed substitutions} and the {type definition}'s {prohibited substitutions}, as defined in Type Derivation OK (Complex) (§3.4.6) (if it is a complex type definition), or given {disallowed substitutions} as defined in Type Derivation OK (Simple) (§3.14.6) (if it is a simple type definition).

From XML Schema Part 2: Datatypes Second Edition...

3 Built-in datatypes