Lista de palavras restritas no esquema XML
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?
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);
}