如何在XSD中使用xs:any?XML扩展校验报错排查
报错原因分析
你的XML中<anti_magic>元素继承了根元素enemy的默认命名空间rubtub2314@gmail.com/Enemy_Data.xml,但XSD里的<xs:any>默认规则是:
- 仅接受无命名空间的元素
- 采用
strict校验模式,要求所有扩展元素必须在当前XSD或导入的XSD中有明确声明
因为<anti_magic>属于目标命名空间且未在XSD中声明,所以校验时触发“元素未声明”的错误。
实现可扩展的解决方案
要让info元素支持自定义参数,需要修改XSD中的<xs:any>标签,添加命名空间和校验模式属性,同时确保XML正确关联XSD:
步骤1:修正XSD的<xs:any>配置
将原XSD中的<xs:any minOccurs="0"/>替换为:
<xs:any minOccurs="0" namespace="##targetNamespace" processContents="lax"/>
属性说明:
namespace="##targetNamespace":允许当前XSD目标命名空间下的自定义元素(和现有属性、元素同属一个命名空间)processContents="lax":宽松校验模式——如果能找到元素的定义就校验合法性,找不到则直接通过(既保证已有元素的校验,又允许未声明的自定义元素)
如果需要支持任意命名空间的扩展元素,可将namespace改为##any。
步骤2:修正XML的命名空间关联
原XML里的xmlns:schema声明无实际作用,需要添加XSD实例命名空间和schema定位,让XML能正确关联到XSD进行校验:
<?xml version="1.0" encoding="utf-8"?> <enemy xmlns="rubtub2314@gmail.com/Enemy_Data.xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="rubtub2314@gmail.com/Enemy_Data.xml Enemy_Data.xsd"> <info id="0" name="warrior"> <atk>1</atk> <def>1</def> <hp>1</hp> <spd>1</spd> <anti_magic>1</anti_magic> </info> <info id="1" name="archer"> <atk>1</atk> <def>1</def> <hp>1</hp> <spd>1</spd> </info> </enemy>
可选进阶:模块化扩展
如果需要对自定义元素做更规范的管理,可以通过XSD的<xs:import>导入其他定义了扩展元素的XSD文件,同时将processContents设为strict,这样既能扩展又能保证自定义元素的合法性。
内容的提问来源于stack exchange,提问作者피스타치오 오명현
相关产品推荐
相关产品推荐

