能否用单个XSD文件切换验证需求与实际XML配置文件?
XML配置文件验证方案建议
问题背景
需求配置demand.xml和实际系统配置actual.xml结构基本一致,但actual.xml包含用户无法控制的系统状态属性(比如<Actuator>元素的connected属性),这类属性在demand.xml中不存在。
我们希望只编写一份针对actual.xml的完整XSD,实现:
- 验证
actual.xml时应用完整XSD规则 - 验证
demand.xml时跳过XSD中对应额外属性的规则
目前用xmlstarlet没找到直接实现的选项,下面是RHEL8标准软件仓库里可用的工具方案:
可用工具方案
1. xsltproc + 自定义XSLT转换
核心思路是用XSLT把完整的actual.xsd转换成适配demand.xml的简化版XSD,再用验证工具处理:
- 编写XSLT脚本,匹配XSD中定义额外属性的节点(比如
<xs:attribute name="connected">)并移除 - 用
xsltproc执行转换,生成临时的demand-temp.xsd - 验证
demand.xml时用这个临时XSD,验证actual.xml时直接用原XSD - 示例命令:
# 生成适配demand的XSD xsltproc strip-actual-attrs.xsl actual.xsd > demand-temp.xsd # 验证demand.xml xmlstarlet val --xsd demand-temp.xsd demand.xml # 验证actual.xml xmlstarlet val --xsd actual.xsd actual.xml
2. xmllint + 参数实体切换
通过在XSD中用参数实体隔离额外属性规则,验证时动态切换实体值:
- 修改
actual.xsd,把额外属性的定义放到参数实体中:
然后在<!ENTITY % actual-attrs " <xs:attribute name='connected' type='xs:boolean' use='required'/> "><Actuator>的属性组里引用%actual-attrs; - 验证
demand.xml时,创建外部实体文件demand-entities.ent,把实体设为空:<!ENTITY % actual-attrs ""> - 用xmllint的
--noent和--dtdattr选项加载外部实体,实现规则切换:# 验证demand.xml(跳过额外属性规则) xmllint --noent --dtdattr --xsd actual.xsd demand.xml # 验证actual.xml(使用完整规则) xmllint --xsd actual.xsd actual.xml
3. Schematron 补充验证
结合XSD和Schematron实现分层验证:
- 先修改完整XSD,把额外属性设为
use="optional",允许demand.xml中不存在这些属性,用XSD验证基础结构 - 编写Schematron规则,检查
demand.xml中不存在那些系统状态属性:<sch:rule context="Actuator"> <sch:assert test="not(@connected)">demand.xml中不允许存在connected属性</sch:assert> </sch:rule> - 用
xsltproc处理Schematron(RHEL8默认自带xsltproc),完成属性检查 - 验证
actual.xml时,直接用完整XSD即可
内容的提问来源于stack exchange,提问作者AdminBee
相关产品推荐
相关产品推荐

