Проверка XML против XSD медленная для длинных строк, если определены ограничения maxLength и образца - PullRequest
1 голос
/ 05 ноября 2019

У нас есть следующий простой тип, определенный в нашем 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>

Обходной путь работает только потому, что реализация Xerces XSSimpleType создает вектор шаблонов регулярных выражений и.{1,255} шаблон будет оценен первым, и он сравнительно быстро завершится неудачей, поэтому проверяющее много времени второе регулярное выражение не будет проверено.

Кто-нибудь сталкивался с той же проблемой и нашел решение, которое не зависит от реализациипроверка XSD? Или есть ли способ заказать проверку xsd: limitction-s в jaxb (чтобы maxLength можно было проверить перед проверкой шаблона)?

Мы создали пример приложения на github: https://github.com/petmaark/xsd-pattern-validation-test

1 Ответ

0 голосов
/ 08 ноября 2019

Xerces2 поддерживает XSD 1.1. К сожалению, этой версии нет в официальном центральном репозитории maven. Вы можете использовать сторонний репозиторий (вам также понадобится icu4j). Если это не является приемлемым решением для вас, вы можете загрузить официальную стабильную версию с веб-сайта Xerces (Xerces2 Java 2.12.0 (XML-схема 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>

Я надеюсь, что это жизнеспособное решение, и я мог бы вам помочь!

...