Estou tentando criar um XSD e tentando escrever a definição com o seguinte requisito:
- Permitir que o elemento filho especificado apareça qualquer número de vezes (0 a ilimitado)
- Permitir que os elementos filhos estejam em qualquer ordem
Olhei em volta e encontrei várias soluções como esta :
<xs:element name="foo">
<xsl:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="child1" type="xs:int"/>
<xs:element name="child2" type="xs:string"/>
</xs:choice>
</xs:complexType>
</xs:element>
Mas, pelo que entendi, xs: choice ainda permite a seleção de um único elemento. Portanto, definir MaxOccurs como ilimitado dessa forma deve significar apenas que "qualquer um" dos elementos filho pode aparecer várias vezes. Isso é correto?
Se a solução acima estiver incorreta, como posso alcançar o que afirmei acima em meu requisito?
EDITAR : E se o requisito for o seguinte?
- O elemento filho1 filho2 pode aparecer qualquer número de vezes (0 a ilimitado)
- Elementos em qualquer ordem
- Os elementos child3 e child4 devem aparecer exatamente uma vez.
Por exemplo, este xml é válido:
<foo>
<child1> value </child1>
<child1> value </child1>
<child3> value </child3>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
mas isso não é (criança ausente3)
<foo>
<child1> value </child1>
<child1> value </child1>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
A formulação alternativa da questão adicionada em uma edição posterior parece ainda sem resposta: como especificar que entre os filhos de um elemento, deve haver um nomeado
child3
, um nomeadochild4
e qualquer número nomeadochild1
ouchild2
, sem restrição na ordem em que as crianças aparecem.Esta é uma linguagem regular definida de forma direta, e o modelo de conteúdo de que você precisa é isomórfico a uma expressão regular que define o conjunto de strings em que os dígitos '3' e '4' ocorrem exatamente uma vez, e os dígitos '1' e '2 'ocorrer qualquer número de vezes. Se não for óbvio como escrever isso, pode ser útil pensar sobre que tipo de máquina de estado finito você construiria para reconhecer tal linguagem. Teria pelo menos quatro estados distintos:
Não importa em que estado o autômato esteja, '1' e '2' podem ser lidos; eles não mudam o estado da máquina. No estado inicial, '3' ou '4' também serão aceitos; nos estados intermediários, apenas '4' ou '3' é aceito; no estado final, nem '3' nem '4' é aceito. A estrutura da expressão regular é mais fácil de entender se primeiro definirmos um regex para o subconjunto de nossa linguagem em que apenas '3' e '4' ocorrem:
Para permitir que '1' ou '2' ocorra qualquer número de vezes em um determinado local, podemos inserir
(1|2)*
(ou[12]*
se nossa linguagem regex aceitar essa notação). Inserindo esta expressão em todos os locais disponíveis, obtemosTraduzir isso em um modelo de conteúdo é simples. A estrutura básica é equivalente ao regex
(34)|(43)
:Inserir uma opção zero ou mais de
child1
echild2
é simples:Se quisermos minimizar o volume um pouco, podemos definir um grupo nomeado para as opções de repetição de
child1
echild2
:No XSD 1.1, algumas das restrições nos
all
grupos foram eliminadas, então é possível definir este modelo de conteúdo de forma mais concisa:Mas, como pode ser visto nos exemplos dados anteriormente, essas mudanças em
all
grupos não alteram de fato o poder expressivo da linguagem; eles apenas tornam a definição de certos tipos de linguagens mais sucinta.fonte
Isso é o que finalmente funcionou para mim:
fonte
Não. A escolha acontece individualmente para cada "repetição" do
xs:choice
que ocorre devido amaxOccurs="unbounded"
. Portanto, o código que você postou está correto e realmente fará o que você quiser conforme escrito.fonte
Você deve descobrir que o seguinte esquema permite o que você propôs.
Isso permitirá que você crie um arquivo como:
O que parece corresponder à sua pergunta.
fonte
minOccurs
emaxOccurs
são restritos a 1 para filhos dexs:all
.Se nenhum dos itens acima estiver funcionando, você provavelmente está trabalhando na tração EDI, onde precisa validar seu resultado em um esquema HIPPA ou qualquer outro xsd complexo para esse assunto. O requisito é que, digamos que haja 8 segmentos REF e qualquer um deles tenha que aparecer em qualquer ordem e também nem todos são necessários, significa dizer que você pode tê-los na seguinte ordem 1 REF, 3 REF, 2 REF, 9 REF. Na situação padrão, o recebimento de EDI falhará, porque o tipo complexo padrão é
A situação é até mesmo complexa quando você está chamando seu elemento por referência e então aquele elemento em seu local original é bastante complexo em si mesmo. por exemplo:
Solução:
Aqui, simplesmente substituir "sequência" por "todos" ou usar "escolha" com combinações mín / máx não funcionará!
Substitua a primeira coisa
"xs:sequence" with "<xs:all>"
agora, você precisa fazer algumas alterações de onde está se referindo ao elemento. Vá para:*** Agora, no segmento acima, adicione o ponto de acionamento no final como este trigger_field = "REF01 _... nome completo .." trigger_value = "38" Faça o mesmo para outros segmentos REF onde o valor do acionador será diferente, como digamos "18 "," XX "," YY "etc .. para que as informações do seu registro agora se pareçam com:
b:recordinfo structure="delimited" field.........Biztalk/2003" trigger_field="REF01_...complete name.." trigger_value="38">
Isso fará com que cada elemento seja único, sendo que todos os segmentos REF (exemplo acima) têm a mesma estrutura como REF01, REF02, REF03. E durante a validação a validação da estrutura está ok, mas não deixa os valores se repetirem porque tenta procurar os valores restantes no próprio REF. Adicionar gatilhos os tornará todos únicos e eles passarão em qualquer ordem e casos situacionais (como usar 5 em 9 e não todos 9/9).
Espero que ajude você, pois gastei quase 20 horas nisso.
Boa sorte
fonte