如何让xmlschema库仅使用本地Schema并映射远程URL到本地目录?
使用xmlschema强制本地Schema校验的最优方案
核心思路
xmlschema自带**资源解析器(Resource Resolver)**机制,不用手动去XML里提取Schema URL,直接通过自定义解析器就能把远程URL映射到本地文件,彻底避免网络请求。
具体实现
1. 编写自定义解析器
继承xmlschema.resolvers.Resolver类,重写resolve方法实现URL到本地路径的映射:
from xmlschema import XMLSchema, Resolver import os class LocalSchemaResolver(Resolver): def __init__(self, local_schema_root): super().__init__() self.local_root = local_schema_root # 本地Schema的根目录 def resolve(self, url, base_url=None): # 匹配目标远程Schema的URL前缀 if url.startswith("https://example.com/"): # 提取URL中相对路径部分,拼接成本地绝对路径 relative_path = url.replace("https://example.com/", "") local_file = os.path.join(self.local_root, relative_path) # 转为file URI格式返回 return f"file://{os.path.abspath(local_file)}" # 可选:拒绝所有未映射的远程Schema,强制仅用本地文件 # raise ValueError(f"禁止使用未映射的远程Schema: {url}") # 或者保留默认逻辑处理其他合法引用 return super().resolve(url, base_url)
2. 用自定义解析器校验XML
创建Schema对象时传入解析器,之后直接校验即可,xmlschema会自动替换所有匹配的远程Schema地址:
# 初始化解析器,指定本地Schema根目录 resolver = LocalSchemaResolver("/path/to/some/dir") # 加载本地Schema(或直接用XML里的引用,解析器会自动替换) schema = XMLSchema("/path/to/some/dir/v1.0.0/schema.xsd", resolver=resolver) # 校验XML文件 schema.validate("target.xml") # 或校验已加载的XML元素 import xml.etree.ElementTree as ET xml_root = ET.parse("target.xml").getroot() schema.validate(xml_root)
为什么这比手动查找更优
- 无需手动解析XML:不用自己提取
xsi:schemaLocation或xsi:noNamespaceSchemaLocation,xmlschema会自动处理所有Schema引用 - 覆盖嵌套引用:能处理主Schema中
import/include的其他远程Schema,手动查找很难覆盖这种场景 - 原生机制更可靠:基于xmlschema的扩展接口实现,兼容性和稳定性比自定义XML解析逻辑更好
额外强化:彻底禁用网络请求
如果要完全杜绝任何网络Schema请求,可在resolve方法中对未映射的URL直接抛出异常,避免意外的网络访问。
内容的提问来源于stack exchange,提问作者Ariyan Eghbal
相关产品推荐
相关产品推荐

