java 使用Xerces的XSD版本1.1验证XML时出错

mbyulnm0  于 11个月前  发布在  Java
关注(0)|答案(2)|浏览(136)

我正在尝试使用XSD 1.1验证XML。我不是这方面的Maven,实际上这是我第一次尝试创建XSD来验证XML。它给了我以下错误:* s4 s-elt-invalid-content。1:“#AnonType_modelomodelos”的内容无效。元素“assert "无效、放错位置或出现太频繁。*
我已经从这里下载了Xerces 1.1版本。https://dlcdn.apache.org//xerces/j/binaries/
我需要验证在可用的、阻塞的和取消的元素中,只有一个元素的值可以是“definitive”,其他元素的值不能是正数或数字。
这就是XML。

<?xml version="1.1" encoding="UTF-8"?>
<modelos xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="sima-modelo.xsd">
    <modelo>
        <tipologia>DIAGNOSTICO</tipologia>
        <claseBase>Autodiag</claseBase>
        <disponible>3</disponible>
        <bloqueado></bloqueado>
        <cancelado>definitivo</cancelado>
        <borradoFisico>false</borradoFisico>
    </modelo>
    <modelo>
        <tipologia>POL</tipologia>
        <claseBase>Policy</claseBase>
        <disponible>30</disponible>
        <bloqueado>10</bloqueado>
        <cancelado>0</cancelado>
        <borradoFisico>true</borradoFisico>
    </modelo>
    <modelo>
        <tipologia>COLAB</tipologia>
        <claseBase>RRHH</claseBase>
        <disponible>1104</disponible>
        <bloqueado>0</bloqueado>
        <cancelado>0</cancelado>
        <borradoFisico>true</borradoFisico>
    </modelo>
</modelos>

字符串
其他版本的XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
           xmlns:xerces="http://xerces.apache.org"
           elementFormDefault="qualified"
           vc:minVersion="1.1">
           
    <xs:element name="modelos">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="modelo" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="tipologia" type="xs:string" />
                            <xs:element name="claseBase" type="xs:string" />
                            <xs:element name="disponible" type="Accion" />
                            <xs:element name="bloqueado" type="Accion" />
                            <xs:element name="cancelado" type="Accion" />
                            <xs:element name="borradoFisico" type="xs:boolean" />
                        </xs:sequence>
                    </xs:complexType>
                    <xs:assert test="count(disponible[.='definitivo']) + count(bloqueado[.='definitivo']) + count(cancelado[.='definitivo']) = 1" />
                    <xs:assert test="not(disponible = bloqueado or disponible = cancelado or bloqueado = cancelado)" />
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:simpleType name="Accion">
        <xs:union>
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:pattern value="" />
                </xs:restriction>
            </xs:simpleType>
            <xs:simpleType id="positiveInteger">
                <xs:restriction base="xs:nonNegativeInteger">
                    <xs:minInclusive value="0" />
                </xs:restriction>
            </xs:simpleType>
            <xs:simpleType>
                <xs:restriction base="xs:token">
                    <xs:enumeration value="definitivo" />
                </xs:restriction>
            </xs:simpleType>
        </xs:union>
    </xs:simpleType>

</xs:schema>


XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
           xmlns:xerces="http://xerces.apache.org"
           elementFormDefault="qualified"
           vc:minVersion="1.1">

    <xs:simpleType name="Accion">
        <xs:union>
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:pattern value=""/>
                </xs:restriction>
            </xs:simpleType>
            <xs:simpleType id="positiveIntegerOrDefinitivo">
                <xs:restriction base="xs:string">
                    <xs:pattern value="\d+|definitivo"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:union>
    </xs:simpleType>

    <xs:element name="modelos">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="modelo" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="tipologia" type="xs:string"/>
                            <xs:element name="claseBase" type="xs:string"/>
                            <xs:element name="disponible" type="Accion"/>
                            <xs:element name="bloqueado" type="Accion"/>
                            <xs:element name="cancelado" type="Accion"/>
                            <xs:element name="borradoFisico" type="xs:boolean"/>
                        </xs:sequence>
                        <xs:assert test="( count(disponible[.='definitivo']) + count(bloqueado[.='definitivo']) + count(cancelado[.='definitivo']) ) = 1"/>
                        <xs:assert test="not(disponible = bloqueado or disponible = cancelado or bloqueado = cancelado)"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>


具有相同消息的XSD的最后一个版本。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
    xmlns:xerces="http://xerces.apache.org"
    elementFormDefault="qualified" vc:minVersion="1.1">

    <xs:element name="modelos" type="ModelosType"/>

    <xs:complexType name="ModelosType">
        <xs:sequence>
            <xs:element name="modelo" type="ModeloType" maxOccurs="unbounded" minOccurs="1"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="ModeloType">
        <xs:sequence>
            <xs:element name="tipologia" type="xs:string" />
            <xs:element name="claseBase" type="xs:string" />
            <xs:element name="disponible" type="Accion" />
            <xs:element name="bloqueado" type="Accion" />
            <xs:element name="cancelado" type="Accion" />
            <xs:element name="borradoFisico" type="xs:boolean" />
        </xs:sequence>
        <xs:assert test="count(disponible[.='definitivo']) + count(bloqueado[.='definitivo']) + count(cancelado[.='definitivo']) = 1" />
        <xs:assert test="not(disponible = bloqueado or disponible = cancelado or bloqueado = cancelado)" />
    </xs:complexType>
    
    <xs:simpleType name="Accion">
        <xs:union>
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:pattern value="" />
                </xs:restriction>
            </xs:simpleType>
            <xs:simpleType id="positiveInteger">
                <xs:restriction base="xs:nonNegativeInteger">
                    <xs:minInclusive value="0" />
                </xs:restriction>
            </xs:simpleType>
            <xs:simpleType>
                <xs:restriction base="xs:token">
                    <xs:enumeration value="definitivo" />
                </xs:restriction>
            </xs:simpleType>
        </xs:union>
    </xs:simpleType>
</xs:schema>


我正在使用Eclipse 2022-12,我认为XML编辑器无法正确验证XSDAssert。* s4 s-elt-invalid-content。1:“#AnonType_modelomodelos”的内容无效。元素“assert”无效、放错位置或出现频率太高。* x1c 0d1x
我在类路径中配置了下载的Xerces 2.12.2版xml schema 1.1的库。这些是jar。它们是正确的吗?

ext-libs/resolver.jar
ext-libs/serializer.jar
ext-libs/xml-apis.jar
ext-libs/xercesImpl.jar
ext-libs/org.eclipse.wst.xml.xpath2.processor_1.2.1.jar
ext-libs/cupv10k-runtime.jar
ext-libs/icu4j.jar


我已经在Maven中搜索了这些库,但显然它们不支持XSD1.1
这是使用您告诉我您已经修改的模式进行验证的结果:

org.xml.sax.SAXParseException: cvc-assertion: Assertion evaluation ('count(*[local-name()=('blocked','cancelled','available') and text()='final']) eq 1') for element 'modelo' on schema type '#AnonType_modelomodelos' did not succeed.


验证方法

static final String W3C_XML_SCHEMA_11_NS_URI = "http://www.w3.org/XML/XMLSchema/v1.1";

    public static boolean validateXMLSchema(String xsdPath, String xmlPath) {

        try {
            SchemaFactory factory = SchemaFactory.newInstance(W3C_XML_SCHEMA_11_NS_URI);
            Schema schema = factory.newSchema(new File(xsdPath));
            Validator validator = schema.newValidator();
            validator.validate(new StreamSource(new File(xmlPath)));
        } catch (IOException | SAXException e) {
            LOGGER.error("Error validando 'modelos.xml' {}: ", xmlPath, e);
            return false;
        }
        return true;
    }


完整的规则是:
我们有一个模型列表,每个模型具有以下属性:

  • typology:允许字符串,是必需的。
  • BaseClass:允许字符串,是必需的。
  • disponible:允许正数或字符串'definitivo'。
  • bloqueado:允许正数或字符串'definitivo'。
  • cancelado:允许正数或字符串'definitivo'。
  • borradoFisico:boolean.
  • 以下规则适用于 disponiblebloqueadocancelado 属性:只有其中一个属性的值为“definitivo”。
  • 它们的值可以为0、任何正数值或空。
  • 如果 disponible 等于 definitivobloqueado + cancelado!= 0,则自定义错误。
  • 如果 bloqueado 等于 definitivo 并且 cancelado 为!= 0,则自定义错误。
pes8fvy9

pes8fvy91#

请尝试以下XSD。
正如@MartinHonnen已经提到的,这些Assert在错误的位置。

  • 我修改了第一个Assert。
  • 请澄清第二个Assert的业务规则。

您可以在这里获得原始的Xerces 2 Java 2.12.2(XML Schema 1.1)The Apache Xerces™ Project - Downloads
我使用的是Oxygen XML Developer v.26.0。它是一个XML IDE。
所以,下面的XSD是合法的。它经过测试,在Oxygen中工作得很好。由于第二个Assert,您的XML示例无效。
正如@MartinHonnen已经指出的,第二个Assert使用的XML元素属于 Accion 用户定义的数据类型。它使用了不同内置数据类型的联合“xs:string”,“xs:nonNegativeString”,“xs:token”。这就是为什么第二个Assert总是验证失败。
当我注解掉第二个Assert时,您的XML就对XSD有效了。

XSD 1.1

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
           xmlns:xerces="http://xerces.apache.org"
           elementFormDefault="qualified" vc:minVersion="1.1">
    <xs:element name="modelos">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="modelo" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="tipologia" type="xs:string"/>
                            <xs:element name="claseBase" type="xs:string"/>
                            <xs:element name="disponible" type="Accion"/>
                            <xs:element name="bloqueado" type="Accion"/>
                            <xs:element name="cancelado" type="Accion"/>
                            <xs:element name="borradoFisico" type="xs:boolean"/>
                        </xs:sequence>
                        <xs:assert test="count(*[local-name()=('bloqueado','cancelado','disponible') and text()='definitivo']) le 1"/>
                        <xs:assert test="not(disponible = bloqueado or disponible = cancelado or bloqueado = cancelado)"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:simpleType name="Accion">
        <xs:union>
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:pattern value=""/>
                </xs:restriction>
            </xs:simpleType>
            <xs:simpleType id="positiveInteger">
                <xs:restriction base="xs:nonNegativeInteger">
                    <xs:minInclusive value="0"/>
                </xs:restriction>
            </xs:simpleType>
            <xs:simpleType>
                <xs:restriction base="xs:token">
                    <xs:enumeration value="definitivo"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:union>
    </xs:simpleType>
</xs:schema>

字符串

wfveoks0

wfveoks02#

这是我的解决方案。谢谢大家!

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
    xmlns:xerces="http://xerces.apache.org" elementFormDefault="qualified"
    vc:minVersion="1.1"
>
    <xs:element name="modelos" type="ModelosType" />
    
    <xs:complexType name="ModelosType">
        <xs:sequence>
            <xs:element name="modelo" type="ModeloType"
                maxOccurs="unbounded" minOccurs="1" />
        </xs:sequence>
    </xs:complexType>
    
    <xs:complexType name="ModeloType">
        <xs:sequence>
            <xs:element name="tipologia" type="xs:string" />
            <xs:element name="claseBase" type="xs:string" />
            <xs:element name="disponible" type="Action" />
            <xs:element name="bloqueado" type="Action" />
            <xs:element name="cancelado" type="Action" />
            <xs:element name="borradoFisico" type="xs:boolean" />
        </xs:sequence>
        <xs:assert
            test="(count(*[local-name()=('bloqueado','cancelado','disponible') and text()='definitivo']) eq 1 or
                   count(*[local-name()=('bloqueado','cancelado','disponible') and text()='definitivo']) eq 0 ) "
            xerces:message="Entre los elementos 'disponible', 'cancelado' y 'bloqueado', sólo uno de ellos puede tener el valor 'definitivo'. Revise el modelo"/>

        <!-- Validación: disponible = 'definitivo' entonces bloqueado y cancelado = 0 -->
        <xs:assert test="if (disponible='definitivo') then ((bloqueado='0' or bloqueado='') and (cancelado='0' or cancelado='') ) else true()"
                    xerces:message="Revise el modelo. Si disponible = 'definitivo' entonces bloqueado y cancelado = 0 o vacío"/>
                  
        <xs:assert test="if (bloqueado='definitivo') then (cancelado='0' or cancelado='') else true()"
                    xerces:message="Revise el modelo. Si bloqueado = 'definitivo' entonces cancelado = 0 o vacío"/>
                    
    </xs:complexType>
    
    <xs:simpleType name="Action">
        <xs:restriction base="xs:string">
            <xs:pattern value="|0|[1-9][0-9]*|definitivo" />
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

字符串

相关问题