繁体   English   中英

如果定义了 maxLength 和模式限制,则针对 XSD 验证 XML 对于长字符串会很慢

[英]Validating XML against XSD is slow for long strings if maxLength and pattern restrictions are defined

我们在 xsd 中定义了以下简单类型:

<xsd:simpleType name="SimpleText255NotBlankType">
        <xsd:annotation>
            <xsd:documentation xml:lang="en">String of maximum 255 characters, not blank</xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:string">
            <xsd:minLength value="1"/>
            <xsd:maxLength value="255"/>
            <xsd:pattern value=".*[^\s].*"/>
        </xsd:restriction>
</xsd:simpleType>

问题是当在输入 xml 中提供一个非常长的字符串(大约 1000000 个字符)作为值时,我们会假设它很快就会因为长度而被视为无效。 实际上验证需要几分钟,因为正则表达式在 maxLength 限制之前被评估。

如果我们以这种方式定义 simpleType,我们找到了解决该问题的方法:

     <xsd:simpleType name="SimpleText255Type">
        <xsd:annotation>
            <xsd:documentation xml:lang="en">String of maximum 255 characters</xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="xsd:string">
            <xsd:minLength value="1"/>
            <xsd:maxLength value="255"/>
            <xsd:pattern value=".{1,255}"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:simpleType name="SimpleText255NotBlankType">
        <xsd:annotation>
            <xsd:documentation xml:lang="en">String of maximum 255 characters, not blank</xsd:documentation>
        </xsd:annotation>
        <xsd:restriction base="SimpleText255Type">
            <xsd:pattern value=".*[^\s].*"/>
        </xsd:restriction>
    </xsd:simpleType>

该解决方法仅适用,因为 XSSimpleType 的 Xerces 实现构建了正则表达式模式的向量,并且将首先评估.{1,255}模式并且它相对较快地失败,因此不会检查耗时的第二个正则表达式。

有没有人遇到同样的问题并找到了解决方案,这不依赖于 xsd 验证的实施? 或者有什么方法可以在 jaxb 中订购 xsd:restriction-s 的验证(以便在检查模式之前验证 maxLength)?

我们在 github 上创建了一个示例应用程序: https://github.com/petmaark/xsd-pattern-validation-test

Xerces2 支持 XSD 1.1。 不幸的是,该版本不在官方 maven 中央存储库中。 您可以使用第三方存储库(您也需要 icu4j)。 如果这对您来说不是一个可行的解决方案,您可以从Xerces 网站下载官方稳定版本(Xerces2 Java 2.12.0 (XML Schema 1.1)),并将其安装到您本地的 maven 存储库。

      <!-- https://mvnrepository.com/artifact/org.opengis.cite.xerces/xercesImpl-xsd11 -->
        <dependency>
            <groupId>org.opengis.cite.xerces</groupId>
            <artifactId>xercesImpl-xsd11</artifactId>
            <version>2.12-beta-r1667115</version>
        </dependency>

        <!--Needed for string-length -->
        <!-- https://mvnrepository.com/artifact/com.ibm.icu/icu4j -->
        <dependency>
            <groupId>com.ibm.icu</groupId>
            <artifactId>icu4j</artifactId>
            <version>4.6</version>
        </dependency>

您还需要替换您的架构版本。

SchemaFactory sf = SchemaFactory.newInstance("http://www.w3.org/XML/XMLSchema/v1.1");

您可以在 XSD 1.1 中使用断言(XSD 1.1 中还有其他有用的新功能,您可以从中受益)。 现在您可以指定验证规则的评估顺序。

<xs:restriction base="xs:string">
            <!--<xs:minLength value="1"/>
            <xs:maxLength value="255"/>
            <xs:pattern value=".*[^\s].*"/>-->

            <xs:assertion test="(string-length($value) >= 1) and (string-length($value) &lt;= 255) and (matches($value, '.*[^\s].*')) "/>

</xs:restriction>

我希望这是一个可行的解决方案,我可以帮助你!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM