为什么 xsd:any 验证没有像我预期的那样工作?

Why isn't xsd:any validation working as I expect?

我想通过模式验证以下 XML,如果 l10n 元素中没有文本,则不应验证它。此外,内容元素对于 XML 是必需的。请有人建议我相关的答案。

要验证的 XML 将是:

<body xmlns="http://iddn.icis.com/ns/test">
   <content>
      <l10n xml:lang="en"></l10n>
   </content>
</body>

我目前使用的架构如下,但它仍然允许验证上述 XML。

<xs:schema elementFormDefault="qualified" targetNamespace="http://iddn.icis.com/ns/test" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:conf="http://iddn.icis.com/ns/config" 
xmlns="http://www.w3.org/1999/xhtml">
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd">
</xs:import>
<xs:simpleType name="nameType">  
    <xs:restriction base="xs:string">  
        <xs:minLength value="1"/>   
    </xs:restriction>  
</xs:simpleType>

<xs:element name="content">
      <xs:complexType mixed="true">
         <xs:sequence>
            <xs:any maxOccurs="unbounded" minOccurs="0" processContents="skip"/>
         </xs:sequence>
      </xs:complexType>
   </xs:element>

<xs:complexType name="i18n-value">
      <xs:sequence>
         <xs:element name="l10n" maxOccurs="unbounded">
            <xs:complexType>
               <xs:simpleContent>
                  <xs:extension base="nameType">
                     <xs:attribute ref="xml:lang" use="required"/>
                  </xs:extension>
               </xs:simpleContent>
            </xs:complexType>
         </xs:element>
      </xs:sequence>
   </xs:complexType>

<xs:element name="body">
  <xs:complexType>
    <xs:sequence><xs:element ref="content"></xs:element></xs:sequence>
  </xs:complexType>
</xs:element>
</xs:schema>

这里在多个层面上存在许多问题。让我们分两个阶段共同解决它们:首先,我们将修复 XSD 阻止任何类型的验证发生的问题。

修复初始 XSD 问题

这个XML

<?xml version="1.0" encoding="utf-16"?>
<body xmlns="http://iddn.icis.com/ns/test"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://iddn.icis.com/ns/test try.xsd">
  <content>
    <l10n xml:lang="en"></l10n>
  </content>
</body>

对这个有效 XSD:

<xs:schema elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://iddn.icis.com/ns/test"
           xmlns:tst="http://iddn.icis.com/ns/test">
  <xs:import namespace="http://www.w3.org/XML/1998/namespace"
             schemaLocation="http://www.w3.org/2001/xml.xsd"/>

  <xs:simpleType name="nameType">  
    <xs:restriction base="xs:string">  
      <xs:minLength value="1"/>
    </xs:restriction>  
  </xs:simpleType>

  <xs:element name="content">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:any maxOccurs="unbounded" minOccurs="0" processContents="skip"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="i18n-value">
    <xs:sequence>
      <xs:element name="l10n" maxOccurs="unbounded">
        <xs:complexType>
          <xs:simpleContent>
            <xs:extension base="tst:nameType">
              <xs:attribute ref="xml:lang" use="required"/>
            </xs:extension>
          </xs:simpleContent>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="body">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="tst:content"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

现在,您对 l10n 不为空的限制仍然有待解决。方法如下:

  • xsd:any/@processContentsskip 更改为 lax 这样你 可以通过元素声明影响 xsd:any 下的验证。在此处阅读有关差异的更多信息:processContents strict vs lax vs skip for xsd:any

  • 实际上为i18n-value定义一个xs:element;有一个类型 仅有定义是不够的。

  • i18n-value 添加到您的 XML。

一共...

最终 XSD 和 XML

XML

<?xml version="1.0" encoding="utf-16"?>
<body xmlns="http://iddn.icis.com/ns/test"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://iddn.icis.com/ns/test try.xsd">
  <content>
    <i18n-value>
      <l10n xml:lang="en"></l10n>
    </i18n-value>
  </content>
</body>

XSD

<xs:schema elementFormDefault="qualified"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://iddn.icis.com/ns/test"
           xmlns:tst="http://iddn.icis.com/ns/test">
  <xs:import namespace="http://www.w3.org/XML/1998/namespace"
             schemaLocation="http://www.w3.org/2001/xml.xsd"/>

  <xs:simpleType name="nameType">
    <xs:restriction base="xs:string">  
      <xs:minLength value="1"/>
    </xs:restriction>  
  </xs:simpleType>

  <xs:element name="content">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:any maxOccurs="unbounded" minOccurs="0" processContents="lax"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="i18n-value">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="l10n" maxOccurs="unbounded">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="tst:nameType">
                <xs:attribute ref="xml:lang" use="required"/>
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="body">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="tst:content"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>