• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

saramgsilva

[XML] Dúvidas sobre XML schema - key/ keyRef ou ID / IDREF

11 mensagens neste tópico

Boa noite,

estou com problemas para fazer um esquema em xml.

Em anexo podemos ver um diagrama em UML, onde tenho 3 classes: Empresa, Departamento e Empregado

e eu pretendo criar um esquema xml para validar ficheiros que contenham a informação sobre o o diagrama anterior.

eu criei o seguinte ficheiro xml de exemplo:


<?xml version="1.0" encoding="utf-8" ?>
<empresa 
         xmlns="http://example.com"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://example.com XMLSchemaTeste.xsd"
         nome="SS" 
         contribuinte="123" 
         idEmpresa="empresa1">
  <departamento sigla="AF" idDepart="departamento1">
    <area> financeira </area>   
  </departamento>
  <departamento sigla="AL" idDepart="departamento2">
    <area> limpeza </area>
  </departamento>

  <empregado idEmp="empregado2">
    <nome>Joao</nome>
    <funcao>TOC</funcao>
    <refDepartamento depart="departamento1"/>
  </empregado>
</empresa>

e o respectivo XML Schema

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://example.com" xmlns:example="http://example.com" targetNamespace="http://example.com" elementFormDefault="qualified" attributeFormDefault="unqualified">
  <!-- empresa -->
  <xs:element name="empresa">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="departamento" type="departType" maxOccurs="unbounded" />
        <xs:element name="empregado" type="empType" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute name="nome" type="xs:string" use="required " />
      <xs:attribute name="contribuinte" type="xs:integer" use="required" />
      <xs:attribute name="idEmpresa" type="xs:ID" />
    </xs:complexType>
  </xs:element>
  <!-- departType -->
  <xs:complexType name="departType">
    <xs:sequence>
      <xs:element name="area" type="xs:string" />
    </xs:sequence>
    <xs:attribute name="idDepart" type="xs:ID" use="required" />
    <xs:attribute name="sigla" type="xs:string" />
  </xs:complexType>
  <!-- empType -->
  <xs:complexType name="empType">
    <xs:sequence maxOccurs="unbounded">
      <xs:element name="nome" type="xs:string" />
      <xs:element name="funcao" type="xs:string" />
      <xs:element name="refDepartamento">
        <xs:complexType>
          <xs:attribute name="depart" type="xs:IDREF" use="required" />
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute name="idEmp" type="xs:ID" use="required" />
  </xs:complexType>
</xs:schema>

como podem reparar eu aqui estou a usar ID's para cada elemento e depois para poder refenciar no elemento empregado o departamento correspondente eu usei o IDREF.

Bem ele validou-me e não tenho erros....mas coloco dúvidas se estarei a fazer bem!!!

eu não quero cometer o erro de repetir informação, por exemplo, eu não quero que aconteço o seguinte:

(basta observar dentro do elemento empregado, coloquei um elemento departamento!)


<?xml version="1.0" encoding="utf-8" ?>
<empresa 
         xmlns="http://example.com"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://example.com XMLSchemaTeste.xsd"
         nome="SS" 
         contribuinte="123" 
         idEmpresa="empresa1">
  <departamento sigla="AF" idDepart="departamento1">
    <area> financeira </area>   
  </departamento>
  <departamento sigla="AL" idDepart="departamento2">
    <area> limpeza </area>
  </departamento>

  <empregado idEmp="empregado2">
    <nome>Joao</nome>
    <funcao>TOC</funcao>
     <departamento sigla="AF" idDepart="departamento1">
    <area> financeira </area>   
    </departamento>
  </empregado>
</empresa>

Peço que me comentem o que fiz, pois estou completamente a nora, sobre o que estou a fazer e estou muito confusa!!

Com análise em alguns livros e exemplos encontrei um exemplo que me confundiu e depois completamente baralhada.... que é o seguinte:


<?xml version="1.0" encoding="utf-8" ?>
<Company
        xmlns="http://example.com"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://example.com XMLSchemaExemplo.xsd">
  <Departments>
    <Department name="Human Resources" building="Building 1" departmentID="hr_dept"/>
    <Department name="Development" building="Building 2" departmentID="development_dept"/>
    <Department name="Testing" building="Building 2" departmentID="testing_dept"/>
  </Departments>
  <Employees>
    <Employee name="Oliver" position="Developer" department="development_dept"/>
    <Employee name="Mwatha" position="Developer" department="development_dept"/>
    <Employee name="Soyapi" position="Developer" department="development_dept"/>
    <Employee name="Mike" position="Testing" department="testing_dept"/>
  </Employees>
</Company>

e o respectivo xml schema:


<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           xmlns="http://example.com" 
           xmlns:example="http://example.com" 
           targetNamespace="http://example.com" 
           elementFormDefault="qualified" 
           attributeFormDefault="unqualified">
  <!-- Company -->
  <xs:element name="Company">
    <xs:complexType>
      <xs:sequence>
        <!-- Departments-->
        <xs:element name="Departments">
          <xs:complexType>
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
              <xs:element name="Department">
                <xs:complexType>
                  <xs:attribute name="name" type="xs:string" />
                  <xs:attribute name="building" type="xs:string" />
                  <xs:attribute name="departmentID" type="xs:string" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <!-- Employees -->
        <xs:element name="Employees">
          <xs:complexType>
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
              <xs:element name="Employee">
                <xs:complexType>
                  <xs:attribute name="name" type="xs:string" />
                  <xs:attribute name="position" type="xs:string" />
                  <xs:attribute name="department" type="xs:string" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
    <!-- KeyDepartmentByID -->
    <xs:key name="KeyDepartmentByID">
      <xs:selector xpath="example:Departments/example:Department" />
      <xs:field xpath="@departmentID" />
    </xs:key>
    <!-- RefEmployeeToDepartment -->
    <xs:keyref name="RefEmployeeToDepartment" refer="example:KeyDepartmentByID">
      <xs:selector xpath="example:Employees/example:Employee" />
      <xs:field xpath="@department" />
    </xs:keyref>
  </xs:element>
</xs:schema>

também este não temm erros e valida!

Afinal que devo pensar eu e que devo eu fazer??? lolol  :wallbash:

bom trabalho

tofas

p.s.: Já agora deixo aqui um excerto de um dado importante:

The <key> declaration, along with the <keyref> declaration, enables you to define a relationship between

two elements. The key/keyref mechanism functions similarly to database keys or to the ID/IDREF mechanism

built into XML DTDs. For example, an element might contain a <key> that is unique within a specified

context or scope. Another element can refer to the key using a <keyref> element. A <key> is always

defined inside an <element> declaration. It contains a <selector> element that defines the context or

scope of the key, and a <field> element that defines the specific key node. Like other elements, it can also

contain an <annotation>

Será que devo concluir que em xml schema devo usar o key e o keyref e o ID/IDREF é para DTD's??? bem sinceramente não sei o que pensar!!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu fiquei com algumas dúvidas também quando vi este teu tópico... então fui pesquisar  as referências para o xchema e encontrei  :

key-Specifies an attribute or element value as a key (unique, non-nullable, and always present) within the containing element in an instance document

keyref-Specifies that an attribute or element value correspond to those of the specified key or unique element

E já agora aqui fica o link para os elementos do xsd pode vir a dar jeito:

http://www.w3schools.com/schema/schema_elements_ref.asp

e o link para os atributos do DTD :

http://www.w3schools.com/dtd/dtd_attributes.asp

Como se pode ver  é tal como disseste cada um é especifico do seu.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

boas,

bem obrigada por confirmares essa dúvida, eu também estava a pensar isto que acabamos de concluir!

Então devo pensar em usar o key e o keyref, terei que usar o Xpath?

Vou analisando, mas aceito sujestões, se alguém poder ajudar agradeço imenso.

Bom trabalho

tofas

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem....que confusão!  :P

Really, i don´t understand nothing!!

no site http://www.w3.org/ que é onde podemos encontrar o que é realmente válido, temos:

Table 2. Simple Types Built In to XML Schema     (ultima versão!!)

e no final podemos reparar na seguinte nota:

Notes: (1) To retain compatibility between XML Schema and XML 1.0 DTDs, the simple types ID, IDREF, IDREFS, ENTITY, ENTITIES, NOTATION, NMTOKEN, NMTOKENS should only be used in attributes

bem uma coisa eu já tinha percebido, que o ID/IDREF só apareciam nos atributos.... e que eram tipos simples, como é o string, integer.....

Poderemos analisar:

5.3 XML Schema Constraints vs. XML 1.0 ID Attributes

o seguinte:

XML 1.0  provides a mechanism for ensuring uniqueness using the ID attribute and its associated attributes IDREF and IDREFS. This mechanism is also provided in XML Schema through the ID, IDREF, and  IDREFS simple types which can be used for declaring XML 1.0-style attributes. XML Schema also introduces new mechanisms that are more flexible and powerful. For example, XML Schema's mechanisms can be applied to any element and attribute content, regardless of its type. In contrast, ID is a type of attribute  and so it cannot be applied to attributes, elements or their content. Furthermore, Schema enables you to specify the scope within which uniqueness applies whereas the scope of an ID is fixed to be the whole document. Finally, Schema enables you to create  keys or a  keyref from combinations of element and attribute content whereas ID has no such facility.

Poderemos também analisar

5.2 Defining Keys & their References

Será que posso considerar correcto o o xml schema que fiz da empresa?

bom trabalho

tofas

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O ID e IDREF também podem ser usados em schemas! Aliás, é o que eu uso sempre.

Se bem percebi, a diferença é que com o ref (que nunca usei) permite indicar em que atributos é que a referência tem que estar definida (coisa que penso não ser possível fazer com o ID/IDREF).

Pelo que percebi, o key/refkey dá-te maior controlo sobre as chaves referências, permitindo que a validação do XML seja mais rígida.

No entanto, com o ID/IDREF não precisas de repetir informação.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas,

é assim em relação ao ref eu penso e tenho a ideia que serve para referenciar elementos globais, e acabamos por repetir informação (penso eu, corrijam-me se estiver errada!!!)

Em relação ao Key/keyref, acho mais complexo e mais rígido, mas tentei testar com o ID/IDREF e penso que também se trabalha bem...apesar que profissionalmente parece mais correcto e mais usal se trabalhar com o Key/keyRef...

acabei de fazer a minha xml schema da empresa:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
  <!-- Company -->
  <xs:element name="Company">
    <xs:complexType>
      <xs:sequence>
        <!-- departamento-->
        <xs:element name="departamento" maxOccurs="unbounded">
          <xs:complexType>
            <xs:attribute name="name" type="xs:string" />
            <xs:attribute name="departamentoID" type="xs:string" />
          </xs:complexType>
        </xs:element >
         <!-- empregado -->
        <xs:element name="empregado" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="nome" type ="xs:string"/>
              <xs:element name="funcao" type="xs:string" />
            </xs:sequence>             
            <xs:attribute name="departamento" type="xs:string" />
          </xs:complexType>
        </xs:element >
      </xs:sequence>
      <xs:attribute  name="nome" type="xs:string"/>
      <xs:attribute name="contribuinte" type="xs:integer"/>
    </xs:complexType>    
    <!-- KeydepartamentoByID -->
    <xs:key name="DepartamentoByID">
      <xs:selector xpath="departamento" />
      <xs:field xpath="@departamentoID" />
    </xs:key>
    <!-- RefempregadoTodepartamento -->
    <xs:keyref name="RefEmpregado" refer="DepartamentoByID">
      <xs:selector xpath="empregado" />
      <xs:field xpath="@departamento" />
    </xs:keyref>
  </xs:element>
</xs:schema>

e o meu xml de exemplo


<?xml version="1.0" encoding="utf-8" ?>
<Company
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="Tofas.xsd"
        nome="SARASILVA, Lda"
        contribuinte="123">
  <departamento name="Recursos Humanos" departamentoID="depart_RH"/>
  <departamento name="Desenvolvimento" departamentoID="depart_desenvolvimento"/>
  <departamento name="Financeira" departamentoID="depart_financeiro"/>

  <empregado departamento="depart_RH">
    <nome>Sara Joana</nome>
    <funcao>Psicologo</funcao>
  </empregado>
  <empregado departamento="depart_desenvolvimento">
    <nome>Maunuel Ferro</nome>
    <funcao>Analista</funcao>
  </empregado>
  <empregado departamento="depart_desenvolvimento">
    <nome>Maria Alves</nome>
    <funcao>Programador</funcao>
  </empregado>
  <empregado departamento="depart_financeiro">
    <nome>Alberto Fernando</nome>
    <funcao>TOC</funcao>
  </empregado>

</Company>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas,

bem já estou mais esclarecida!E penso que o melhor mesmo é usar o Key/KeyRef para podermos referenciar num elemento um outro elemento. Pensoo que é o mais correcto para validar essa informação, e temos um controlo muito maior sobre a referência. coisa que o ID/IDREF não permite, pois como estes são symple types.

Através do Key e KeyRef temos que no key dizemos o elemento e o campo que "vais ser a chave" e no keyref o elemento que vai ter o campo que recebe a chave do elemento que foi definido na key.Ora vejam:


<!-- KeydepartamentoByID -->
    <xs:key name="DepartamentoByID">
      <xs:selector xpath="departamento" /> <!-- aqui temos o elemento que contem chave-->
      <xs:field xpath="@departamentoID" /> <!-- aqui temos o campo que vai ser a chave-->
    </xs:key>
    <!-- RefempregadoTodepartamento -->
    <xs:keyref name="RefEmpregado" refer="DepartamentoByID">
      <xs:selector xpath="empregado" /> <!-- aqui temos o elemento que "recebe" a chave-->
      <xs:field xpath="@departamento" /> <!-- aqui temos o campo que vai ser a referencia da chave-->
    </xs:keyref>

(este código faz parte do esquema que apresentei no tópico anterior!)

desculpem se fui confusa...tentei expressar-me da melhor forma!

bom trabalho

tofas

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já agora, aproveito este tópico para resolver uma dúvida minha. Como é que faço para validar o Xml com o schema criado? Com DTDs consigo, mas o schema não entendo como.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Usa o xsi:schemaLocation na raiz para especificares o ficheiro que contém o Schema. Depois vais precisar de uma aplicação qualquer para tratar da validação.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Usa o xsi:schemaLocation na raiz para especificares o ficheiro que contém o Schema. Depois vais precisar de uma aplicação qualquer para tratar da validação.

O problema é que ainda não encontrei nenhuma aplicação que faça isso.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podes usar o Oxygen. Tens um trial de 30 dias (e quando acabarem esses 30 dias acho que podes pedir outra licença de 30 dias).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora