如何使用 XML 架构或其他 XML 语言使符合要求的 XML 分析器填充缺少的属性和值

How to make a conformant XML parser fill-in a missing attribute and value, using an XML Schema or another XML language

提问人: 提问时间:11/2/2020 更新时间:11/2/2020 访问量:266

问:

我正在寻找一种简单、可重用的方法,我可以让 XML 解析器将属性及其关联值添加到特定名称的任何元素中,该元素缺少该属性和/或具有不同的值,或引发解析错误。理想情况下,该解决方案由最新版本的主要浏览器支持,但浏览器对 XML 的支持通常不是那么好,而且浏览器之间的差异很大,因此如果它没有浏览器支持也没关系。

事实上,我会接受任何标准化的XML扩展/命名空间/等来完成这项工作。

为了更好地说明我所要做的事情,让我们以 XHTML 标签为例。我有一个元素的标签名称是 ,它来自 XHTML 命名空间 ,我正在寻找缺少任何属性 , , 或 的元素的任何实例,或者具有与我希望它们具有的值不同的值,或者标签之间有任何文本内容(它应该是一个自闭合标签)。script*script**xhtml:**xhtml:script**async**defer**type*

我正在尝试自动制作任何如下所示的脚本标签:

<script src="main.js" />

转换为:

<script async="async" defer="defer" type="module" src="main.js" />

或者,至少导致 XML 解析器出错并在此时停止解析。

理想情况下,XML 文件的作者甚至不允许使用这些属性,因为它们应该这样做 始终自动填充正确的值。

我曾认为XSL(T)可以为此工作,但这需要生成一个全新的输出文件。如果我误解了XSL,请随时纠正我。 虽然,我确实希望它像使用 XSL 一样简单;要使用 XSL,只需添加一个 XML 样式表即可对源文档执行的操作。 另外,我不确定浏览器对 XSL 2.0 的支持程度如何,如果它是

正因为如此,我开始研究其他相关的XML技术,遇到了XML模式(XSD)。

在网络上搜索有关它们的任何信息后,我发现 w3schools 对 XML 架构属性元素的属性表示如下:fixed

当未指定其他值时,也会自动将固定值分配给该属性。但与默认值不同;如果指定 fixed 以外的其他值,则文档将被视为无效。

所以,这似乎正是我想要的,在环顾四周后,我做了以下工作:

<?xml version="1.0" encoding="UTF-8?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="script">
        <xs:simpleType>
            <xs:attribute name="type" type="xs:string" fixed="module" />
            <xs:attribute name="async" type="xs:string" fixed="async" />
            <xs:attribute name="defer" type="xs:string" fixed="defer" />
            <xs:attribute name="src" type="xs:string" use="required" />
        </xs:simpleType>
    </xs:element>
</xs:schema>

但这似乎对文档的解析没有任何影响。

XML xslt xhtml

评论

0赞 Martin Honnen 11/2/2020
是否使用支持 W3C 架构语言的验证分析器?浏览器当然不支持这一点。例如,Java 和 .NET 平台都支持基于模式的验证。但是,当然,您需要正确获取targetNamespace(如果您说XHTML命名空间中有元素,则架构需要具有该targetNamespace),我认为在解析较大文档时仅声明单个元素可能还不够,尽管这可能取决于解析器和/或解析器设置。

答:

0赞 Michael Kay 11/2/2020 #1

Saxon 的模式处理器有一个扩展 saxon:preprocess

https://saxonica.com/documentation/index.html#!schema-processing/extensions11/preprocess

在我看来,这可以用来实现您的要求。如果 (a) 定义属性的默认值,并且 (b) 定义 saxon:preprocess 方面,则在预处理表达式中,您可以接受任何输入值并将其转换为有效值。

若要实际输出包含结果值的文档,需要将经过验证/预处理的 XML 作为输入提供给架构感知 XSLT 样式表,该样式表将输入的类型化值复制为输出的字符串值:。<xsl:attribute name="{name()}" select="data()}"/>

这在浏览器中不起作用(Saxon-JS 不支持模式处理)。

评论

0赞 11/5/2020
哈,我想我最终还是会使用 XSL。那好吧。