Вычисление максимально возможной длины строки, соответствующей регулярному выражению в xsd (C #)

1

Я работаю с XSD, и у меня есть доступ к шаблону из XSD в виде строки. Пример:

<xsd:pattern value="[0-9]{8}"/>

дает мне строку С#

string pattern = "[0-9]{8}";

Из строки шаблона, которую я получаю из XSD (которая может быть любой допустимой строкой XSD), я пытаюсь выработать максимально возможную длину, которую может содержать содержимое поля в XML.

В этом тривиальном примере, очевидно, 8 - я мог бы понять это, проверив {n} и предполагая, что длина. В других шаблонах я также мог проверить * или + и предположить неограниченное - но я ищу более общий подход, который можно использовать для этого.

Обратите внимание, что строка шаблона не гарантируется совместимость с классами.Net Regex.

У меня также есть доступ к классу XmlSchemaPatternFacet, который я использую для синтаксического анализа XSD, если это поможет.

Спасибо за любую помощь, которую вы можете дать

  • 0
    Спасибо за редактирование названия :)
Теги:
xsd

3 ответа

3
Лучший ответ

Вы почти наверняка должны проанализировать регулярное выражение, чтобы достичь этого. Например, вы можете взять парсер регулярных выражений с открытым исходным кодом в Saxon (который реализует правильный диалект regex). Это создает дерево подвыражений, и вы можете добавить метод для вычисления максимальной длины соответствия для каждого узла в дереве. Класс Operation, представляющий узел в дереве, уже (в 9.6) имеет методы getMatchLength() и getMinimumMatchLength(), и было бы достаточно просто добавить getMaximumMatchLength() который работает одинаково.

0

С этими определениями:

<xs:simpleType name="ST_exactly8digitsString">
    <xs:restriction base="xs:string">
        <xs:pattern value="[0-9]{8}"/>
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="ST_upto8digitsString">
    <xs:restriction base="xs:string">
        <xs:pattern value="[0-9]{0,8}"/>
    </xs:restriction>
</xs:simpleType>

все они подтвердят:

<upto8digitsString>12345678</upto8digitsString>
<upto8digitsString>12345</upto8digitsString>
<exactly8digitsString>12345678</exactly8digitsString>

это не будет:

<exactly8digitsString>12345</exactly8digitsString>
<upto8digitsString>123456789</upto8digitsString>

Хотя, я думаю, вы ищите:

<xs:simpleType name="ST_anyNoDigitsString">
    <xs:restriction base="xs:string">
        <xs:pattern value="[0-9]*"/>
    </xs:restriction>
</xs:simpleType>

Все они соответствуют:

<anyNoDigitsString>12345678900000000</anyNoDigitsString>
<anyNoDigitsString>88</anyNoDigitsString>
<anyNoDigitsString></anyNoDigitsString>
<anyNoDigitsString>0</anyNoDigitsString>

По сравнению с другими регулярными выражениями.Net регулярные выражения схемы XML ограничены в функциях. Поскольку они используются только для проверки того, соответствует ли весь элемент шаблону или нет. Afaik, допускаются только жадные кванторы ?, *, + И {n,m}.

  • 0
    Регулярное выражение в моем посте было только примером. Я ищу общий способ узнать, учитывая шаблон из xsd, какова самая длинная запись в xml.
  • 0
    Вопрос был неясен в первую очередь. Я предполагаю, что цель проверки является самодостаточной . Если ваша цель состоит в том, чтобы иметь определенное ограничение для строк, вы изобретаете ограничение шаблона . Если проверка XML не пройдена, очевидно, что ваши спецификации длины были превышены. Вы идете в обратном направлении, используя XmlSchemaPatternFacet для определения длины, с недостатками imho. Просто проверьте XML с некоторыми шаблонами. Если это работает, ожидания оправдались ... Бесполезно делать какие-то выводы по длине паттерна.
Показать ещё 1 комментарий
0

Я предполагаю, что это будет очень сложно. Со встроенными скобками вам придется рекурсивно искать длину шаблона.

Изменение: я нашел https://github.com/moodmosaic/Fare, который соответствует вашим требованиям.

var regex = @"((mailto\:|(news|(ht|f)tp(s?))\://){1}\S+)";
var xeger = new Xeger(regex);

var result = Regex.IsMatch(xeger.Generate(), regex);

Также я не уверен, что найдет максимально возможный ответ, но это может быть началом.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню