我正在寻找一种简单、可重复使用的方法,让XML解析器将属性及其关联值添加到特定名称的任何元素中,这些元素缺少属性和/或具有不同的值,或者引发解析错误。理想情况下,该解决方案由最新版本的主要浏览器支持,但浏览器对XML的支持通常不太好,而且不同浏览器之间的支持差异很大,所以如果没有浏览器支持也没关系。
事实上,我愿意接受任何标准化的XML扩展/名称空间等来实现这一点。
为了更好地说明我要做什么,让我们以XHTMLscript
标记为例。我有一个元素的标记名为*script*
,它来自XHTML命名空间*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-stylesheet
即可。此外,如果XSL 2.0是,我也不确定浏览器对它的支持程度
正因为如此,我开始研究其他相关的XML技术,遇到了XML模式(XSD(。
在网上搜索了关于它们的任何信息后,我发现w3schools在XMLSchemaattribute
元素的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>
但这似乎对文档的解析没有任何影响。
https://saxonica.com/documentation/index.html#!模式处理/扩展11/预处理
我突然想到,这可以用来实现您的需求。如果您(a(为属性定义一个默认值,并且(b(定义一个saxon:preprocess方面,那么在预处理表达式中,您可以接受任何输入值并将其转换为有效值。
要实际输出包含结果值的文档,您需要将经过验证/预处理的XML作为输入提供给模式感知的XSLT样式表,该样式表将输入的类型值复制为输出的字符串值:<xsl:attribute name="{name()}" select="data()}"/>
。
这在浏览器中不起作用(SaxonJS不支持模式处理(。