kb.erickguedes.com
XML: Estrutura e Processamento

XML em Integração e Boas Práticas

Aula 5 de 5

XML em APIs: SOAP vs REST

SOAP usa XML como formato nativo com envelope, header e body. REST pode usar XML como alternativa ao JSON.

Requisição SOAP

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <auth:token xmlns:auth="http://exemplo.com/auth">ABC123</auth:token>
  </soap:Header>
  <soap:Body>
    <ns:consultarCliente xmlns:ns="http://exemplo.com/servico">
      <ns:cpf>123.456.789-00</ns:cpf>
    </ns:consultarCliente>
  </soap:Body>
</soap:Envelope>

Resposta REST XML

# Requisição REST com XML
curl -X POST https://api.exemplo.com/clientes \
  -H "Content-Type: application/xml" \
  -H "Accept: application/xml" \
  -d '<?xml version="1.0"?>
<cliente>
  <nome>João Silva</nome>
  <email>[email protected]</email>
</cliente>'

XML em Configurações

Spring XML

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

  <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
    <property name="jdbcUrl" value="jdbc:postgresql://localhost:5432/db"/>
    <property name="username" value="admin"/>
  </bean>
</beans>

Maven POM

<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.exemplo</groupId>
  <artifactId>meu-projeto</artifactId>
  <version>1.0.0</version>
  <dependencies>
    <dependency>
      <groupId>com.thoughtworks.xstream</groupId>
      <artifactId>xstream</artifactId>
      <version>1.4.20</version>
    </dependency>
  </dependencies>
</project>

Segurança: Prevenção de XXE

XXE (XML External Entity) é uma vulnerabilidade crítica quando o parser processa entidades externas.

// VULNERÁVEL - processa entidades externas
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new FileReader("input.xml")));

// SEGURO - desabilita entidades externas
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
DocumentBuilder builder = factory.newDocumentBuilder();
# Python seguro - desabilitar entidades
from lxml import etree
parser = etree.XMLParser(resolve_entities=False, no_network=True)
tree = etree.parse("input.xml", parser)

Validação com XSD em Pipeline

# Pipeline de validação e transformação
#!/bin/bash
set -e

ARQUIVO=$1
SCHEMA=$2

echo "1. Validando contra schema..."
xmllint --schema "$SCHEMA" "$ARQUIVO" --noout || {
  echo "ERRO: Validação falhou"
  exit 1
}

echo "2. Extraindo dados..."
xmllint --xpath "//dados/item" "$ARQUIVO"

echo "3. Convertendo para formato de saída..."
xsltproc transform.xsl "$ARQUIVO" > output.html

echo "Pipeline concluído com sucesso!"

Lab: Integração XML Completa

# 1. Documento de pedido
cat << 'EOF' > pedido.xml
<?xml version="1.0"?>
<pedido>
  <cliente email="[email protected]"/>
  <item sku="NOTE-001" qtd="2"/>
  <item sku="MOUSE-003" qtd="1"/>
</pedido>
EOF

# 2. Schema de validação
cat << 'EOF' > pedido.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="pedido">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="cliente">
          <xs:complexType>
            <xs:attribute name="email" use="required">
              <xs:simpleType>
                <xs:restriction base="xs:string">
                  <xs:pattern value="[^@]+@[^@]+\.[a-z]+"/>
                </xs:restriction>
              </xs:simpleType>
            </xs:attribute>
          </xs:complexType>
        </xs:element>
        <xs:element name="item" maxOccurs="unbounded">
          <xs:complexType>
            <xs:attribute name="sku" type="xs:string" use="required"/>
            <xs:attribute name="qtd" use="required">
              <xs:simpleType>
                <xs:restriction base="xs:integer">
                  <xs:minInclusive value="1"/>
                </xs:restriction>
              </xs:simpleType>
            </xs:attribute>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
EOF

# 3. Pipeline completo
echo "=== Validando ==="
xmllint --schema pedido.xsd pedido.xml --noout && echo "OK"
echo "=== Extraindo SKUs ==="
xmllint --xpath "//item/@sku" pedido.xml
echo "=== Teste XXE: documento malicioso ==="
cat << 'EOF' > xxe-teste.xml
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<dados>&xxe;</dados>
EOF
echo "Com segurança desabilitada, isso leria arquivos do sistema!"
xmllint --noent xxe-teste.xml

Sempre valide entrada XML, desabilite entidades externas, e prefira libraries modernas.