如何使用 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
我正在寻找一种简单的、可重复使用的方法,让我可以得到一个 XML 解析器来将一个属性及其关联值添加到任何具有特定名称的元素,该元素缺少属性 [=58] =] 有不同的值,或者抛出解析错误。理想情况下,该解决方案得到主流浏览器最新版本的支持,但浏览器对 XML 的支持通常不是那么好,而且浏览器之间差异很大,所以如果不支持浏览器也没关系.
事实上,我会接受任何标准化的 XML extension/namespace/etc 来完成这项工作。
为了更好地说明我正在尝试做的事情,让我们以 XHTML script
标记为例。我有一个标签名称为 *script*
的元素,它来自 XHTML 命名空间 *xhtml:*
,我正在寻找缺少任何属性 [=20] 的元素 *xhtml:script*
的任何实例=]、*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-Schemas (XSD)。
在网上搜索有关它们的任何信息后,我发现 w3schools 在 XML 架构 attribute
元素上说了以下内容fixed
属性:
A fixed value is also automatically assigned to the attribute when no other value is specified. But unlike default values; if you specify another value than the fixed, the document is considered invalid.
所以,这似乎正是我要找的东西,在多看了几眼之后,我做了以下内容:
<?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>
但这似乎对文档的解析没有任何影响。
Saxon 的模式处理器有一个扩展 saxon:preprocess
https://saxonica.com/documentation/index.html#!schema-processing/extensions11/preprocess
我突然想到这可以用来实现您的要求。如果您 (a) 为属性定义一个默认值,并且 (b) 定义一个 saxon:preprocess 构面,那么在预处理表达式中您可以接受任何输入值并将其转换为有效值。
要实际输出包含结果值的文档,您需要提供 validated/preprocessed XML 作为 schema-aware XSLT 样式表的输入,它会复制输入成为输出的字符串值:<xsl:attribute name="{name()}" select="data()}"/>
.
这在浏览器中不起作用(Saxon-JS 不支持模式处理)。
我正在寻找一种简单的、可重复使用的方法,让我可以得到一个 XML 解析器来将一个属性及其关联值添加到任何具有特定名称的元素,该元素缺少属性 [=58] =] 有不同的值,或者抛出解析错误。理想情况下,该解决方案得到主流浏览器最新版本的支持,但浏览器对 XML 的支持通常不是那么好,而且浏览器之间差异很大,所以如果不支持浏览器也没关系.
事实上,我会接受任何标准化的 XML extension/namespace/etc 来完成这项工作。
为了更好地说明我正在尝试做的事情,让我们以 XHTML script
标记为例。我有一个标签名称为 *script*
的元素,它来自 XHTML 命名空间 *xhtml:*
,我正在寻找缺少任何属性 [=20] 的元素 *xhtml:script*
的任何实例=]、*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-Schemas (XSD)。
在网上搜索有关它们的任何信息后,我发现 w3schools 在 XML 架构 attribute
元素上说了以下内容fixed
属性:
A fixed value is also automatically assigned to the attribute when no other value is specified. But unlike default values; if you specify another value than the fixed, the document is considered invalid.
所以,这似乎正是我要找的东西,在多看了几眼之后,我做了以下内容:
<?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>
但这似乎对文档的解析没有任何影响。
Saxon 的模式处理器有一个扩展 saxon:preprocess
https://saxonica.com/documentation/index.html#!schema-processing/extensions11/preprocess
我突然想到这可以用来实现您的要求。如果您 (a) 为属性定义一个默认值,并且 (b) 定义一个 saxon:preprocess 构面,那么在预处理表达式中您可以接受任何输入值并将其转换为有效值。
要实际输出包含结果值的文档,您需要提供 validated/preprocessed XML 作为 schema-aware XSLT 样式表的输入,它会复制输入成为输出的字符串值:<xsl:attribute name="{name()}" select="data()}"/>
.
这在浏览器中不起作用(Saxon-JS 不支持模式处理)。