Мне нужен XSD, в котором либо комбинация из двух элементов ИЛИ 1 другого элемента является обязательной

Основываясь на ответе @ Vittim.us выше. Мне нравится контроль, который дает мне его метод, что упрощает его расширение, но мне нужно было добавить нечувствительность к регистру и ограничить совпадение целыми словами с поддержкой пунктуации. (например, «ванна» находится в «ванне», но не «купается»)

Регулярное выражение для пунктуации произошло из: https://stackoverflow.com/a/25575009/497745 ( Как я могу отделить все знаки препинания от строки в JavaScript с помощью regex? )

function keywordOccurrences(string, subString, allowOverlapping, caseInsensitive, wholeWord)
{

    string += "";
    subString += "";
    if (subString.length <= 0) return (string.length + 1); //deal with empty strings

    if(caseInsensitive)
    {            
        string = string.toLowerCase();
        subString = subString.toLowerCase();
    }

    var n = 0,
        pos = 0,
        step = allowOverlapping ? 1 : subString.length,
        stringLength = string.length,
        subStringLength = subString.length;

    while (true)
    {
        pos = string.indexOf(subString, pos);
        if (pos >= 0)
        {
            var matchPos = pos;
            pos += step; //slide forward the position pointer no matter what

            if(wholeWord) //only whole word matches are desired
            {
                if(matchPos > 0) //if the string is not at the very beginning we need to check if the previous character is whitespace
                {                        
                    if(!/[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&\(\)*+,\-.\/:;<=>?@\[\]^_`{|}~]/.test(string[matchPos - 1])) //ignore punctuation
                    {
                        continue; //then this is not a match
                    }
                }

                var matchEnd = matchPos + subStringLength;
                if(matchEnd < stringLength - 1)
                {                        
                    if (!/[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&\(\)*+,\-.\/:;<=>?@\[\]^_`{|}~]/.test(string[matchEnd])) //ignore punctuation
                    {
                        continue; //then this is not a match
                    }
                }
            }

            ++n;                
        } else break;
    }
    return n;
}

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

0
задан ElPayode 13 July 2018 в 09:48
поделиться

1 ответ

У меня есть обходной путь. Это не оптимальное решение, но очень работоспособное.

<xs:schema>
  <xs:element name="ExternalReference" type="xs:string"/>
  <xs:group name="InternalReference">
    <xs:sequence>
      <xs:element name="HeaderNumber" type="xs:int"/>
      <xs:element name="LineNumber" type="xs:int"/>
      <xs:element ref="ExternalReference" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
  </xs:group>
  <xs:group name="External">
    <xs:sequence>
      <xs:element ref="ExternalReference" minOccurs="1" maxOccurs="1"/>
    </xs:sequence>
  </xs:group>
  <xs:group name="Reference">
    <xs:choice>
      <xs:group ref="InternalReference"/>
      <xs:group ref="External"/>
    </xs:choice>
  </xs:group>
  <xs:complexType name="message">
    <xs:sequence>
      <xs:group ref="Reference" minOccurs="1"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="Message" type="message"/>
</xs:schema>

Я все еще надеюсь на лучший способ.

0
ответ дан ElPayode 17 August 2018 в 13:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: