1

我需要使用动态属性名称验证 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>
4

1 回答 1

4

data-*在将 XML提供给验证函数之前,预处理 XML 以删除属性。否则我无法使用 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 编写的属性做了一些事情。如果你很好奇,它的代码位于 W3C Nu Html Checker 源的 GitHub 存储库中,这里:

https://github.com/validator/validator/tree/master/src/nu/validator/xml/dataattributes

请参阅中的filterAttributes代码DataAttributeDroppingContentHandlerWrapper.java

它本质上是一个 SAX 过滤器,在验证函数之前的解析事件的解析时间工作。

如果您更加好奇,还有其他预处理过滤器的代码可以做类似的事情:

无论如何,您大致了解:如果您的源代码中存在任何无法在 RelaxNG 或 XSD 中表达验证逻辑的标记结构,那么您实质上过滤(预处理)源代码以从验证函数中隐藏该标记.

于 2017-09-10T23:26:36.383 回答