我需要使用动态属性名称验证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>
答案 0 :(得分:4)
预处理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验证器)后端为data-*
属性执行某些操作,这些属性在功能上与XSLT转换相同,但是用Java编写。如果你很好奇,它的代码在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
- 通过将custom elements放入the accompanying RelaxNG grammar允许元素基本上出现在任何地方的特殊命名空间来过滤掉nu.validator.xml.templateelement.TemplateElementDroppingContentHandlerWrapper
template
element - 过滤掉{{3}}子树 - 基本上只是将它们放在地板上,因为HTML规范允许template
子树基本上包含任何内容;所以没有必要让验证功能对template
子树进行任何检查无论如何,你得到一般的想法:如果你的源中有任何标记构造的情况,你无法表达RelaxNG或XSD中的验证逻辑,那么你基本上过滤(预处理)源来隐藏该标记验证功能。