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命名空间但未出现在模式中的元素正在通过验证,而在模式中出现的其他元素可以通过赋予它们无效属性而失败. 所以: 例如,这传递验证: <?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! --> ... (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |