微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

xml – 使用“对嵌套元素进行不一致的XSD验证

我正在开发一个工具来帮助用户创作X HTML-ish文档,这些文档在性质上与JSP文件类似.这些文档是 XML,可以在XHTML命名空间中包含任何格式良好的标记,并且它们之间编织的是我产品命名空间中的元素.除此之外,该工具使用XSD验证输入.

输入示例:

<?xml version="1.0"?>
<markup>
  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="https://my_tag_lib.example.com/">
    <c:section>
      <c:paragraph>
        <span>This is a test!</span>
        <a href="http://www.google.com/">click here for more!</a>
      </c:paragraph>
    </c:section>
  </html>
</markup>

我的问题是XSD验证的行为不一致取决于我嵌套元素的深度.我想要的是https://my_tag_lib.example.com/名称空间中的所有元素都要根据模式进行检查,而名称空间http://www.w3.org/1999/xhtml中的任何元素都可以被宽容地容忍.我想不列出我的XSD中允许的所有HTML元素 – 用户可能想要使用仅在某些浏览器等上可用的模糊元素.相反,我只想使用< xs白名单列出属于命名空间的任何元素:任何取代. 我发现的是,在某些情况下,属于my_tag_lib命名空间但未出现在模式中的元素正在通过验证,而在模式中出现的其他元素可以通过赋予它们无效属性而失败. 所以:
*有效元素根据XSD架构进行验证
*验证器会跳过无效元素?

例如,这传递验证:

<?xml version="1.0"?>
<markup>
  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="https://my_tag_lib.example.com/">
    <c:section>
      <div>
        <c:my-invalid-element>This is a test</c:my-invalid-element>
      </div>
    </c:section>
  </html>
</markup>

但后来验证失败了:

<?xml version="1.0"?>
<markup>
  <html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="https://my_tag_lib.example.com/">
    <c:section>
      <div>
        <c:paragraph my-invalid-attr="true">This is a test</c:paragraph>
      </div>
    </c:section>
  </html>
</markup>

为什么要针对已识别元素的模式验证属性,而未识别的元素似乎根本没有被消毒?这里的逻辑是什么?我一直在使用xmllint进行验证:

xmllint --schema markup.xsd example.xml

这是我的XSD文件

文件:markup.xsd

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <xs:import namespace="http://www.w3.org/1999/xhtml" schemaLocation="html.xsd" />
  <xs:element name="markup">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:element ref="xhtml:html" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

文件:html.xsd

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3.org/1999/xhtml">
  <xs:import namespace="https://my_tag_lib.example.com/" schemaLocation="my_tag_lib.xsd" />
  <xs:element name="html">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:any processContents="lax" namespace="http://www.w3.org/1999/xhtml" />
        <xs:any processContents="strict" namespace="https://my_tag_lib.example.com/" />
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

文件:my_tag_lib.xsd

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="https://my_tag_lib.example.com/">
  <xs:element name="section">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:any processContents="lax" namespace="http://www.w3.org/1999/xhtml" />
        <xs:any processContents="strict" namespace="https://my_tag_lib.example.com/" />
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="paragraph">
    <xs:complexType mixed="true">
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:any processContents="lax" namespace="http://www.w3.org/1999/xhtml" />
        <xs:any processContents="strict" namespace="https://my_tag_lib.example.com/" />
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>
div元素未声明,因此如果不接受模式中的无效类型,则没有任何内容可以保留,并且paragraph元素不允许my-invalid-attr.

也许一些例子可能会更清楚.

如果声明了元素(例如html,section,paragraph)并且其内容来自taglib命名空间(您声明为具有processContents =“strict”),则它们将被视为严格.这意味着必须声明属性或子元素.这应该验证失败:

<html>
    <c:my-invalid-element>This is a test</c:my-invalid-element>
</html>

这样:

<c:section>
    <c:my-invalid-element>This is a test</c:my-invalid-element>
</c:section>

这个:

<div>
    <c:paragraph>
         <c:my-invalid-element>This is a test<c:my-invalid-element>
    </c:paragraph>
</div>

而这(因为属性内容的一部分):

<c:paragraph my-invalid-attr="true">This is a test</c:paragraph>

但是如果元素未声明(例如div),它将匹配xs:any声明.没有声明限制div的内容,所以它允许任何东西.所以这应该通过验证:

<div>
    <c:my-invalid-element>This is a test</c:my-invalid-element>
</div>

由于c:my-invalid-element也未声明,因此它将允许任何内容属性.这是有效的:

<div>
    <c:my-invalid-element invalid-attribute="hi"> <!-- VALID -->
        <c:invalid></c:invalid>
        <html></html>
    </c:my-invalid-element>
</div>

但是如果将无效元素放在html中,它将失败:

<div>
    <c:my-invalid-element invalid-attribute="hi">
        <html><c:invalid></c:invalid></html>  <!-- NOT VALID -->
    </c:my-invalid-element>
</div>

如果您在声明的元素中使用未声明的属性(与xs:any不匹配),无论您的嵌套有多深,都会发生同样的情况:

<div>
    <c:my-invalid-element invalid-attribute="hi"> <!-- VALID -->
        <c:invalid>
            <b> 
                <c:section bad-attribute="boo"></c:section> <!-- FAILS! -->
 ...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。