Pergunta

Estou escrevendo um esquema XML e preciso impedir que o texto de um elemento corresponda a determinados valores. (Por exemplo, o elemento variatleblename não pode corresponder 'int', 'byte', 'string' etc.)

Eu tentei usar uma restrição com um elemento de padrão semelhante a "^(int | byte | string)", mas sem sucesso.

Você conhece a maneira de formatar a expressão regular ou qualquer outra maneira de fazer isso funcionar?

Foi útil?

Solução

Após a verificação tripla que o esquema XML (xsd) regexes verdade Não suporta nenhum dos recursos que facilitariam essa tarefa (particularmente LookaHeads e âncoras), eu criei uma abordagem que parece funcionar. Usei o modo de espaçamento livre para facilitar a leitura, mas esse é outro recurso que o sabor XSD não suporta.

  [^ibs].* |
  i(.{0,1} | [^n].* | n[^t].* | nt.+) |
  b(.{0,2} | [^y].* | y[^t].* | yt[^e].* | yte.+) |
  s(.{0,4} | [^t].* | t[^r].* | tr[^i].* | tri[^n].* | trin[^g].* | tring.+)

A primeira alternativa corresponde a qualquer coisa que não começa com a letra inicial de nenhuma das palavras -chave. Cada uma das outras alternativas de nível superior corresponde a uma string que começa com a mesma letra que uma das palavras-chave, mas:

  • é mais curto que a palavra -chave,
  • tem uma segunda letra diferente, terceira letra diferente, etc., ou
  • é mais longo que a palavra -chave.

Observe que as regexes XSD não suportam âncoras explícitas (ou seja, ^, $, \A, \z), mas todas as partidas estão implicitamente ancoradas nas duas extremidades.

Um problema em potencial que posso ver: se a lista de palavras -chave for longa, você poderá enfrentar um limite no comprimento da regex.

Outras dicas

Tem que ser o esquema W3C (também conhecido como "esquema XML")? Ou uma alternativa padrão gostaria Relaxng trabalhar? Posso estar errado, mas pensei que tinha algumas imagens na combinação de restrições, incluindo a capacidade de fazer interseções.

Sem aparência negativa, isso é bastante tedioso. Anexado está um regex que funciona com alguns testes de unidade. Isso está escrito no Perl, não no XSD, mas é um regex bastante básico, por isso deve funcionar ... você deve remover o espaço em branco do regex antes de usá -lo. Adicionei o espaço em branco apenas para facilitar a leitura.

Nota: Não sei se " a" e " z" são permitidos no XSD. Caso contrário, substitua por "^" e "$", respectivamente.

use Test::More 'no_plan';

my $re = qr/\A(\z|[^ibs]                                                        
   |i(\z|[^n]|n(\z|[^t]|t.))                                                    
   |b(\z|[^y]|y(\z|[^t]|t(\z|[^e]|e.)))                                         
   |s(\z|[^t]|t(\z|[^r]|r(\z|[^i]|i(\z|[^n]|n(\z|[^g]|g.))))))/x;

for my $str ( qw(inter bytes ins str strings in sdgsdfger i b s by byt bite st \
str stri strin strink) ) {
   like($str, $re, $str);
}

for my $str ( qw(int byte string) ) {
   unlike($str, $re, $str);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top