[英]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) <= 255) and (matches($value, '.*[^\s].*')) "/>
</xs:restriction>
我希望这是一个可行的解决方案,我可以帮助你!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.