给xsd:any指定的元素的结构可以验证吗?

时间:2018-12-19 10:49:07

标签: xml validation xsd

我偶然发现了有关w3schools entry的xsd:any(请不要评论一般使用w3schools作为参考,这个问题是关于w3schools在这种情况下是否正确)。它基本上描述了您将此元素作为基础(在某些模式family.xsd中):

<xs:element name="person">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="firstname" type="xs:string"/>
      <xs:element name="lastname" type="xs:string"/>
      <xs:any minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

然后,您定义其他模式children.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="https://www.w3schools.com"
           xmlns="https://www.w3schools.com"
           elementFormDefault="qualified">
  <xs:element name="children">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="childname" type="xs:string"
                    maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema> 

现在他们说,基于这些架构,您可以编写有效的文档:

<?xml version="1.0" encoding="UTF-8"?>
<persons xmlns="http://www.microsoft.com"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.microsoft.com family.xsd
                             https://www.w3schools.com children.xsd">
  <person>
    <firstname>Hege</firstname>
    <lastname>Refsnes</lastname>
    <children>
      <childname>Cecilie</childname>
    </children>
  </person>
  <!-- ... -->
</persons>

假设未显示其定义的周围结构有效,我的问题是:验证者是否可以在这里实际检查<children>元素的正确结构,如果可以,如何检查? / p>

我的理解是,第二个模式定义了一个文档,其根是<children>元素。但是,XSD不提供从元素名称到类型的直接映射,因为在不同作用域中具有相同名称的元素可能具有不同的类型(对吗?)。因此,正如我所看到的,验证器无法知道<children>内部给出的<person>元素实际上应该根据第二个架构中的定义进行验证。因此,第二个模式在这里是无用的,即使<children>包含某些元素<foo/>,该文档也仍然有效。正确吗?

2 个答案:

答案 0 :(得分:1)

processContents="strict"上的xs:any属性表示,此处显示的元素必须具有全局元素声明,并且必须对该声明有效。对于任何给定的元素名称,只能有一个全局元素声明(全局声明是显示为xs:schema的子元素的声明)。

由于名称空间,您的文档无效。 children.xsd模式文档的目标名称空间是https://www.w3schools.com,但是实例中的children元素在名称空间http://www.microsoft.com中。因此,验证器应报告未找到children的全局元素声明。

答案 1 :(得分:0)

A possible solution

1) Update your xsd with:

<xs:any minOccurs="0" processContents="strict"/>

This will prevent the validator from accepting whathever "any" xml.

2) Design a super schema being the union of all existing schemas, and use this super schema as input of the Validator.

For instance (in Java):

Source xmlSource = // the xml to validate;
Source schemaSource = // your super xsd
Schema schema = schemaFactory.newSchema(schemaSource);
Validator validator = schema.newValidator();
validator.validate(xmlSource);