如何验证具有 HTML5 data-* 属性的文档?
How to validate documents with HTML5 data-* attributes?
我需要使用动态属性名称验证 XML,例如 data-*
。现在我正在使用 RelaxNG 架构,但它不支持动态属性名称。有什么选择?我找不到任何相关内容..
XML 示例:
<?xml version="1.0" encoding="utf-8"?>
<body xml:lang="cs" ns="www.x.y">
<h id="x" ctime="2017-09">Heading..</h>
<desc kw="kw">Desc..</desc>
<section>
<h data-foo="bar" id="one" short="One">First heading</h>
<desc>Desc...</desc>
<p>Content..</p>
<ul data-buz="fuz">
<li data-switch="click">list item</li>
<li>list item 2</li>
</ul>
</section>
</body>
预处理 XML 以删除 data-*
属性,然后再将其提供给验证函数。否则我无法使用 RelaxNG 或其他基于语法的模式语言对其进行验证。
就预处理 XML 而言,使用现有 XML 工具链执行此操作的一种方法是:运行 通过 XSLT 转换删除 data-*
属性,但按原样传递所有其他属性:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
<xsl:output method="xml" indent="no"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*[starts-with(name(), 'data-')]"/>
</xsl:stylesheet>
<xsl:template match="@*[starts-with(name(), 'data-')]"/>
是那里的重要部分。这会导致任何 data-*
属性被丢弃在地板上。该 XSL 样式表的其余部分只是一个基本的“识别转换”,它按原样传递来自源 XML 的所有其他内容。
W3C Nu Html Checker (HTML5 validator) backend does something for data-*
attributes that’s functionally the same as that XSLT transformation, but written in Java. If you’re curious, the code for it is within the GitHub repo for the W3C Nu Html Checker sources,此处:
https://github.com/validator/validator/tree/master/src/nu/validator/xml/dataattributes
见the filterAttributes
code in DataAttributeDroppingContentHandlerWrapper.java
它本质上是一个 SAX 过滤器,在验证功能之前的解析时间关闭解析事件。
如果你甚至 更多 好奇,还有其他预处理过滤器做类似事情的代码:
nu.validator.xml.customelements.NamespaceChangingContentHandlerWrapper
—filters out custom elements by putting them in a special namespace that the accompanying RelaxNG grammar 允许来自的元素基本上出现在任何地方
nu.validator.xml.templateelement.TemplateElementDroppingContentHandlerWrapper
—filters out template
element 子树——本质上只是将它们丢在地上,因为 HTML 规范允许 template
子树基本上包含任何东西;所以根本不需要验证函数对那些 template
子树进行任何检查
无论如何,您得到了一般的想法:如果您的源代码中有任何您无法在 RelaxNG 或 XSD 中表达验证逻辑的标记构造情况,那么您实际上过滤(预处理)了source 从验证函数中隐藏该标记。
我需要使用动态属性名称验证 XML,例如 data-*
。现在我正在使用 RelaxNG 架构,但它不支持动态属性名称。有什么选择?我找不到任何相关内容..
XML 示例:
<?xml version="1.0" encoding="utf-8"?>
<body xml:lang="cs" ns="www.x.y">
<h id="x" ctime="2017-09">Heading..</h>
<desc kw="kw">Desc..</desc>
<section>
<h data-foo="bar" id="one" short="One">First heading</h>
<desc>Desc...</desc>
<p>Content..</p>
<ul data-buz="fuz">
<li data-switch="click">list item</li>
<li>list item 2</li>
</ul>
</section>
</body>
预处理 XML 以删除 data-*
属性,然后再将其提供给验证函数。否则我无法使用 RelaxNG 或其他基于语法的模式语言对其进行验证。
就预处理 XML 而言,使用现有 XML 工具链执行此操作的一种方法是:运行 通过 XSLT 转换删除 data-*
属性,但按原样传递所有其他属性:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
<xsl:output method="xml" indent="no"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*[starts-with(name(), 'data-')]"/>
</xsl:stylesheet>
<xsl:template match="@*[starts-with(name(), 'data-')]"/>
是那里的重要部分。这会导致任何 data-*
属性被丢弃在地板上。该 XSL 样式表的其余部分只是一个基本的“识别转换”,它按原样传递来自源 XML 的所有其他内容。
W3C Nu Html Checker (HTML5 validator) backend does something for data-*
attributes that’s functionally the same as that XSLT transformation, but written in Java. If you’re curious, the code for it is within the GitHub repo for the W3C Nu Html Checker sources,此处:
https://github.com/validator/validator/tree/master/src/nu/validator/xml/dataattributes
见the filterAttributes
code in DataAttributeDroppingContentHandlerWrapper.java
它本质上是一个 SAX 过滤器,在验证功能之前的解析时间关闭解析事件。
如果你甚至 更多 好奇,还有其他预处理过滤器做类似事情的代码:
nu.validator.xml.customelements.NamespaceChangingContentHandlerWrapper
—filters out custom elements by putting them in a special namespace that the accompanying RelaxNG grammar 允许来自的元素基本上出现在任何地方nu.validator.xml.templateelement.TemplateElementDroppingContentHandlerWrapper
—filters outtemplate
element 子树——本质上只是将它们丢在地上,因为 HTML 规范允许template
子树基本上包含任何东西;所以根本不需要验证函数对那些template
子树进行任何检查
无论如何,您得到了一般的想法:如果您的源代码中有任何您无法在 RelaxNG 或 XSD 中表达验证逻辑的标记构造情况,那么您实际上过滤(预处理)了source 从验证函数中隐藏该标记。