禁止以root身份使用导入的元素

时间:2017-10-24 17:27:49

标签: xml xsd xsd-validation xml-validation

如何防止导入的XSD中的全局定义元素成为有效XML文档中的根元素?

a.xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://example.org/a" elementFormDefault="qualified"
 xmlns="http://example.org/a" xmlns:ns="http://example.org/a"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="elementA">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="x">
                <xs:complexType>
                    <xs:attribute name="name" type="xs:string" use="required"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
    <xs:key name="keyX">
      <xs:selector xpath="ns:x"/>
      <xs:field xpath="@name"/>
    </xs:key>
  </xs:element>
</xs:schema>

b.xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://example.org/b" elementFormDefault="qualified"
 xmlns="http://example.org/b" xmlns:a="http://example.org/a"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="a.xsd" namespace="http://example.org/a"/>
  <xs:element name="elementB">
    <xs:complexType>
      <xs:all>
        <xs:element ref="a:elementA"/>
      </xs:all>
    </xs:complexType>
  </xs:element>
</xs:schema>

我遇到的问题是,在针对b.xsd验证XML文件时,elementA是一个有效的根元素(因为导入)。如何更改模式,使elementB是唯一有效的根元素?请注意,我确实需要elementA内的密钥,这比我在SO上找到的其他类似案例更难。

2 个答案:

答案 0 :(得分:1)

XSD未指定允许哪些顶级元素声明或类型定义是验证开始的那些。设计是为了在验证时指定。由于XSD规范没有规定用于调用验证的特定接口,因此您使用的机制的详细信息会有所不同(并非所有验证器都知道它们应该允许用户指定预期的元素或验证时根的类型。

如果您用于验证的软件具有调用时选项或参数,用于指定验证根目录中可接受的元素声明,请使用它们。如果没有,请使用应用程序级代码,以确保您不仅处理有效元素,而且处理代码准备处理的元素。

答案 1 :(得分:0)

如果元素在XSD中直接或通过import或include全局定义,则可以将其用作根元素。如果您不希望通过导入或包含打开根元素选项,则在导入或包含的XSD中不声明全局元素 - 在定义根元素的组成时使用所有本地声明的元素。 / p>

当然,您仍然可以在导入和包含的XSD中定义类型。