使用BaseX、XQuery及Postman操作时,XML验证报错'targetNamespace属性不允许出现在Reservas元素中'的原因排查
解决XML验证错误:
Attribute 'targetNamespace' is not allowed to appear in element 'Reservas' 这个错误的核心原因很明确:targetNamespace是XML Schema(XSD)专属的属性,只能用在XSD的<xs:schema>根元素上,绝对不能加到XML实例文件的元素里。你的XML根元素<Reservas>非法添加了这个属性,而XSD定义里并没有给<Reservas>声明可以接受这个属性,所以验证器抛出了cvc-complex-type.3.2.2错误。
接下来一步步解决问题:
1. 修复XML实例文件
首先移除<Reservas>上的targetNamespace属性,同时还要修正日期格式(XSD的xs:date要求YYYY-MM-DD,你原来的DD-MM-YYYY不符合规范):
<?xml version="1.0" encoding="utf-8"?> <Reservas xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ipp.estg.pt/Dados_clientes CommonTypes.xsd" xmlns="http://www.ipp.estg.pt/Dados_clientes" > <num_familia>1</num_familia> <num_elementos>1</num_elementos> <preferencia_dias> <data>2021-12-22</data> <data>2021-12-23</data> <data>2021-12-24</data> </preferencia_dias> <cliente> <nome>Nicolas</nome> <data_nascimento>1999-08-22</data_nascimento> <pais>Portugal</pais> <cidade_origem>Amarante</cidade_origem> </cliente> </Reservas>
2. 修正XSD中的潜在问题
你的XSD还有几个不匹配的地方,不修复的话验证还是会失败:
PreferenciasType的序列是空的,但XML里有<data>元素,需要添加对应的元素定义ClientesType的定义和XML里的<cliente>结构不匹配(XSD定义的是多个clientes元素的序列,XML里是单个cliente元素直接包含个人信息)- 错误地给
xsi命名空间绑定了自定义地址,应该保留标准的XMLSchema-instance地址 - 添加
elementFormDefault="qualified"确保命名空间下的所有元素都被正确验证
修正后的XSD:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.ipp.estg.pt/Dados_clientes" xmlns="http://www.ipp.estg.pt/Dados_clientes" elementFormDefault="qualified"> <!-- Elemento completo --> <xs:element name="Reservas"> <xs:complexType> <xs:sequence> <xs:element name="num_familia" type="FamiliaType"></xs:element> <xs:element name="num_elementos" type="xs:int"></xs:element> <xs:element name="preferencia_dias" type="PreferenciasType"></xs:element> <!-- 调整为匹配XML的ElementosType,而不是原来的ClientesType --> <xs:element name="cliente" type="ElementosType"></xs:element> </xs:sequence> </xs:complexType> </xs:element> <!-- COMPLEX TYPE RELATIVO AOS ELEMENTOS DA FAMILIA --> <xs:complexType name="ElementosType"> <xs:sequence> <xs:element name="nome" type="xs:string" /> <xs:element name="data_nascimento" type="xs:date" /> <xs:element name="pais" type="xs:string" /> <xs:element name="cidade_origem" type="xs:string" /> </xs:sequence> </xs:complexType> <!-- TYPE USADA SOBRE AS DATAS DE PREFERENCIA --> <xs:complexType name="PreferenciasType"> <xs:sequence minOccurs="1" maxOccurs="5"> <!-- 添加data元素定义,匹配XML结构 --> <xs:element name="data" type="xs:date" /> </xs:sequence> </xs:complexType> <!-- NÚMERO DE FAMILIAS MAXIMAS PERMITIDOS --> <xs:simpleType name="FamiliaType"> <xs:restriction base="xs:int"> <xs:minInclusive value="1" /> <xs:maxInclusive value="50000" /> </xs:restriction> </xs:simpleType> </xs:schema>
3. 优化XQuery代码
你的XQuery代码里的语法小问题也需要调整,确保验证和数据库操作正确执行:
xquery version "3.0"; module namespace page = 'http://basex.org/examples/web-page'; declare %updating %rest:path("addAgendamento") %rest:POST("{$xml}") %rest:consumes('application/xml') function page:add($xml as item()) { let $xsd := "CommonTypes.xsd" // 先执行验证,失败会直接抛出错误 let $validation := validate:xsd($xml, $xsd) return ( update:output("Insert successful."), db:add("Dados_clientes", $xml, "Dados_clientes.xml") ) };
做完这些调整后,再用Postman发送POST请求,应该就能通过验证并成功插入数据了。
内容的提问来源于stack exchange,提问作者gipsywontmakeit
相关产品推荐
相关产品推荐

