首页 > 解决方案 > XSD 元素与不同命名空间中的类型声明?

问题描述

我有许多由另一个导入的 XSD 模式。在针对主要包装器类 XSD 进行验证时,验证器似乎没有将类型与正确的 XSD 相关联。它似乎以某种方式混淆了命名空间。

作为一个最小示例,请考虑以下两个 XSD,每个都定义了自己的类型和命名空间:

a.xsd定义一个a-type

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:tns="http://a"
           targetNamespace="http://a"
           elementFormDefault="qualified"
           attributeFormDefault="qualified">

  <xs:simpleType name="a-type">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>

</xs:schema>

b.xsd定义 a b-type

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:tns="http://b"
           targetNamespace="http://b"
           elementFormDefault="qualified"
           attributeFormDefault="qualified" >

  <xs:simpleType name="b-type">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>

</xs:schema>

ab.xsd定义它自己的ab-type,利用上面定义的类型:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:a="http://a"
           xmlns:b="http://b"
           xmlns:tns="http://ab"
           targetNamespace="http://ab"
           elementFormDefault="qualified"
           attributeFormDefault="qualified" >

  <xs:import namespace="http://a" schemaLocation="a.xsd"/>
  <xs:import namespace="http://b" schemaLocation="b.xsd"/>

  <xs:complexType name="ab-type">
    <xs:sequence maxOccurs="1">
      <xs:element name="a-tag" type="a:a-type"/>
      <xs:element name="b-tag" type="b:b-type"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="ab-tag" type="tns:ab-type"/>

</xs:schema>

当我根据以下 XML 文件对其进行验证时:

<?xml version="1.0" encoding="UTF-8"?>
<ab:ab-tag
    xmlns:ab="http://ab"
    xmlns:a="http://a"
    xmlns:b="http://b">
  <a:a-tag>A</a:a-tag>
  <b:b-tag>B</b:b-tag>
</ab:ab-tag>

我收到以下错误xmllint --schema ab.xsd ab.xml

ab.xml:6:元素a-tag:架构有效性错误:元素{http://a}a-tag:不需要此元素。预期为 ( {http://ab}a-tag)。ab.xml 无法验证

验证时我也有类似的错误xsd11-validator.jar。因此,即使我指定ab.xsdisa-tag的类型a:a-tag,它似乎仍然试图将其与来自 的命名空间相关联ab

标签: xmlxsdxsd-validationxml-validationxmllint

解决方案


从另一个 XML 命名空间在 XSD 中定义的类型与在其他 XML 命名空间定义的元素不同。

要放置a-taghttp://a命名空间中,您必须在该命名空间中实际放置一个元素声明......

a.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:tns="http://a"
  targetNamespace="http://a"
  elementFormDefault="qualified"
  attributeFormDefault="qualified">

  <xs:simpleType name="a-type">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <xs:element name="a-tag" type="tns:a-type"/>
</xs:schema>

b.xsd

同样,b-taghttp://b命名空间中声明:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:tns="http://b"
  targetNamespace="http://b"
  elementFormDefault="qualified"
  attributeFormDefault="qualified" >

  <xs:simpleType name="b-type">
    <xs:restriction base="xs:string"/>
  </xs:simpleType>
  <xs:element name="b-tag" type="tns:b-type"/>
</xs:schema>

ab.xsd

ab.xsd中,从 更改xs:element/@name@ref

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:a="http://a"
  xmlns:b="http://b"
  xmlns:tns="http://ab"
  targetNamespace="http://ab"
  elementFormDefault="qualified"
  attributeFormDefault="qualified" >

  <xs:import namespace="http://a" schemaLocation="a.xsd"/>
  <xs:import namespace="http://b" schemaLocation="b.xsd"/>

  <xs:complexType name="ab-type">
    <xs:sequence maxOccurs="1">
      <xs:element ref="a:a-tag"/>
      <xs:element ref="b:b-tag"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="ab-tag" type="tns:ab-type"/>
</xs:schema>

ab.xml

ab.xml 没问题

<?xml version="1.0" encoding="UTF-8"?>
<ab:ab-tag
  xmlns:ab="http://ab"
  xmlns:a="http://a"
  xmlns:b="http://b">
  <a:a-tag>A</a:a-tag>
  <b:b-tag>B</b:b-tag>
</ab:ab-tag>

如上定义,ab.xml现在对ab.xsd有效。


推荐阅读