0

Entende aqueles xmlns:xsi="..." ou xsi="schemaLocation="..."? Look inside!

#Spring Framework #Java #Maven
Willams Sousa
Willams Sousa

Java e seus XML...

Você entende aqueles xmlns:xsi="..." ou xsi="schemaLocation="..."?


Fala devs, beleza?


Neste artigo vou falar um pouco sobre aqueles XMLs usados no Java: pom.xml, spring.xml, web.xml, persistence.xml entre outros. Mais precisamente spring.xml e pom.xml, mas vale para os demais.


Pois bem, geralmente o pessoal sempre diz: isso não precisa decorar, a IDE preenche pra você, etc.. Certo? Bom, chegou a hora de abrir a caixa e olhar dentro dela em vez de ficar sempre incomodado em ter que copiar e colar sem fazer ideia do que significa aquelas letrinhas cheias de URIs. A ler vamos:


XML


Não é objetivo aqui detalhar o que é XML, então veremos apenas uma ideia geral do que é e pra que serve XML.


XML significa eXtensible Markup Language. Colocando de outra forma, é uma linguagem de marcação extensível.


Pra entender XML é interessante compará-lo com HTML. O html pega a informação (um texto) e marca alguns locais do texto. Se no texto temos um <b> e um </b> delimitando uma palavra, esta eventualmente ficará em negrito.


O HTML tem, a princípio, o interesse em dar dicas de como a informação deve ser apresentada.


O XML, por sua vez, tem como foco marcar a informação de tal forma que, quem esteja lendo, saiba o que cada parte significa. P.ex.:


<carta>
<para>João</para>
<de>Maria</de>
<assunto>Confidencial</assunto>
<texto>Não acredite na velha dos doces!</texto>
</carta>


Esse texto, sem as marcações, ficaria:


"João Maria Confidencial Não acredite na velha dos doces!"


Um software, ou mesmo um ser humano, teria dificuldades em entender o que cada parte significa e do que se trata o texto.


Podemos entender que, enquanto que o HTML se preocupa em apresentar os dados com foco na sua aparência, XML se preocupa em transportar dados com foco no que ele realmente é. As tags do XML não são predefinidas e devem ser modeladas com foco na informação e suas partes.


Vamos ver de perto um XML real em ação: o famigerado pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.willams.entendendoxml</groupId>
	<artifactId>entendendoxml</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>Entendendo XML</name>
	<description>Entendendo XML</description>

	<properties>
		<spring.version>5.2.8.RELEASE</spring.version>
	</properties>
	
	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>
</project>


Como sabemos, as tags vão dizer o que aquela parte do texto significa. Temos um projeto cujas partes envolvem propriedades, dependências, identificadores para grupos e artefatos, temos também versões, etc. Porém, é justamente a parte que foge da ideia principal do XML - ser facilmente lido por seres humanos - que nos aflige, isto é, a parte onde temos urls aparentemente arbitrárias, tal como:


<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

...

</project>


Em um XML para o spring, p.ex., podemos encontrar nessa parte o seguinte:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">

...

</beans>


DTD e XSD


A primeira coisa a ser feita é entender que, porque XML não tem tags predefinidas, é necessário que saibamos quais são as tags de um determinado XML. Isso é feito indicando um arquivo que define as tags permitidas, isto é feito com um documento contendo as definições para o XML, ele pode ser um DTD ou um XSD. 


O primeiro significa "Document Type Definition" e pode ser referenciado da seguinte forma:


<!DOCTYPE carta [
<!ELEMENT carta (para,de,assunto,texto)>
<!ELEMENT para (#PCDATA)>
<!ELEMENT de (#PCDATA)>
<!ELEMENT assunto (#PCDATA)>
<!ELEMENT texto (#PCDATA)>
]>
<carta> ... </carta>


ou como arquivo exteno:


<!DOCTYPE carta SYSTEM "carta.dtd"> 
<carta> ... </carta>



Veja maiores detalhes em https://www.w3schools.com/xml/xml_dtd_intro.asp


O segundo significa "XML Schema Definition" e pode ser referenciado da seguinte forma:


<?xml version="1.0"?>

<carta
xmlns="https://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.w3schools.com/xml carta.xsd">
 ...
  
</carta>


Por favor, para maiores detalhes veja: https://www.w3schools.com/xml/schema_intro.asp


Pense que essas definições são como classes, e seu XML é como um objeto que usa essas classes. Como você saberia que determinado objeto tem o método show()? Basta você digitar um ponto e a IDE mostra, você diria. Ok, também, mas a ideia é que o método está devidamente 'documentado' em uma classe que tem como objetivo definir quais métodos e atributos um determinado objeto tem. Essa é a função dos DTDs (ou sua versão mais legal, o XSD).


Namespaces


O artigo começa de verdade exatamente agora. 


A primeira parte importante é que um XML pode conter namespaces, esses namespaces servem para resolver conflitos entre os nomes.


Observe que para a tag <table> poderiamos ter:


<table>
<tr>
<td>Uvas</td>
<td>Bananas</td>
</tr>
</table>


(aquela do HTML, lembra?)


ou


<table>
<name>Mesa para escritório</name>
<width>80</width>
<length>120</length>
</table>


(sim, uma mesa mesmo, tipo mesa de escritório ou mesa de cozinha)


Uma vez que cada table pode ter significados diferentes, o XML permite que você crie um namespace (espaço de nomes) para cada uma.


<html:table>
<html:tr>
<html:td>Uvas</html:td>
<html:td>Bananas</html:td>
</html:tr>
</html:table>


(namespace html)


e


<moveis:table>
<moveis:name>Mesa para escritório</moveis:name>
<moveis:width>80</moveis:width>
<moveis:length>120</moveis:length>
</moveis:table>


(namespace moveis)


Esses namespaces são definidos na tag raiz (root) do seu XML dai teríamos algo como:


<root 
xmlns:html="URI do namespace html"
xmlns:moveis="URI do namespace moveis"

<html:table >
...
</html:table>

<moveis:table >
...
</moveis:table>

</root>


A URI serve apenas para identificar o namespace, ela não precisa ser um local real na internet. Se você colocar no navegador a URI "http://maven.apache.org/POM/4.0.0" vai dar página não encontrada (404), uma vez que o interesse é apenas identificar de forma única esse 'recurso'. Aconselho ver na wikipedia sobre URI, URN e URL.


Além dos namespaces que possuem um prefixo (moveis e html, no nosso exemplo) podemos especificar o namespace padrão. Qualquer nome que não tiver prefixo virá do namespace padrão. P.ex.:



<root xmlns="URI do namespace html" xmlns:moveis="URI do namespace moveis"

<table >
...
</table>

<moveis:table >
...
</moveis:table>

</root>


Agora que sabemos o que são namespaces, podemos ver o pom.xml e entender o significado:


pom.xml e spring.xml


<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">


(Por hora, ignore a última linha)


Veja que, para esse pom.xml, o namespace padrão tem o identificador "http://maven.apache.org/POM/4.0.0" e temos outro namespace - xsi - cuja URI é "http://www.w3.org/2001/XMLSchema-instance".


Para um exemplo com mais namespaces vejamos agora um arquivo de configuração do spring framework:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util.xsd">


(por hora, ignore tudo que não for xmlns:xxx)


XSI e SchemaLocation


Ok, agora que conhecemos namespaces, chegou a hora do XSD e sua relação com xsi:schemaLocation.


Note que tanto no pom.xml quanto no spring.xml temos o namespace xsi, uma vez que você usa esse namespace poderá usar o atributo schemaLocation para indicar onde está o documento xsd para as definições de determinado namespace. A forma de usar esse atributo é:


xsi:schemaLocation = {URI do namespace} [espaço] {URL do documento xsd de definição deste namespace}


Assim, para o pom.xml temos:


xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"


e para o spring.xml temos:


xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util.xsd"


Entendendo o que é necessário e sabendo que esses valores são fixos, podemos lembrar sem muito esforço. P.ex.:


Para o pom.xml sabemos que a URI do namespace padrão é "http://maven.apache.org/POM/4.0.0" e que o xsd desse namespace é "https://maven.apache.org/xsd/maven-4.0.0.xsd". Sabemos também que o namespace xsi é "http://www.w3.org/2001/XMLSchema-instance".


Com isso já conseguimos formar o xml:


<project namespacepadrão = "uri dele"
namespace:xsi = "uri dele"
xsi:localização do esquema = 
"uri do namespace [espaço] uri do arquivo.xsd dele
"uri do namespace [espaço] uri do arquivo.xsd dele
...
"


Só é preciso lembrar o uri_namespace e o url_namespace.xsd para cada XML que você usar, seja o persistence.xml, o spring.xml, o pom.xml, etc.


Note que a url do namespace xsi é igual para todos: "http://www.w3.org/2001/XMLSchema-instance".


Claro que eu decorei isso tudo porque sou nerdão (: , mas o mais importante não é decorar, e sim entender o que cada coisa tá fazendo. Este artigo é pra quem nunca estudou sobre XML (como eu) e fica incomodado com tanta sopa de letrinhas só dando copy&paste.


Para maiores detalhes sobre XML, como criar nossos próprios esquemas xsd ou dtd, etc., veja https://www.w3schools.com/xml/default.asp


Obrigado pela atenção, valeu!

0
3

Comentários (0)

Tento ser um sujeito legal e gosto de aprender linguagens de programação.

Brasil