Skip to content

Criar validações para os elementos <media> e <inline-media> #1100

@Rossi-Luciano

Description

@Rossi-Luciano

Objetivo

Implementar validações para os elementos <media> e <inline-media> conforme a especificação SPS 1.10, aumentando a conformidade de X% para 70% (7 de 10 regras).

Nota: Algumas validações para <media> e <inline-media> podem já estar parcialmente implementadas no repositório. Este Issue visa reavaliar, complementar e garantir cobertura completa das regras SPS 1.10.


Contexto

Os elementos <media> e <inline-media> referenciam arquivos externos de objetos multimídia (vídeos, áudios, documentos, planilhas, etc.), exceto figuras estáticas. Validações corretas garantem que atributos obrigatórios estejam presentes, que combinações de mime-type/mime-subtype sejam válidas, e que boas práticas de acessibilidade sejam seguidas.

Conformidade atual: X de 10 regras implementadas (X%)
Meta após implementação: 7 de 10 regras (70%)


Documentação SPS

Referência oficial: https://docs.google.com/document/d/1GTv4Inc2LS_AXY-ToHT3HmO66UT0VAHWJNOIqzBNSgA/edit?tab=t.0#heading=h.media

Regras principais conforme SPS 1.10:

  1. Atributos obrigatórios (ambos elementos):

    • @id (obrigatório)
    • @mime-type (obrigatório)
    • @mime-subtype (obrigatório)
    • @xlink:href (obrigatório)
  2. Valores comuns para @mime-type:

    • application - Planilhas Excel, documentos Word, apresentações PowerPoint, PDFs, arquivos compactados
    • video - Vídeos
    • audio - Áudios
  3. Extensões obrigatórias para @mime-subtype:

    • Vídeo: mp4
    • Áudio: mp3
    • Arquivos compactados: zip
    • Outros formatos: consultar IANA Media Types
  4. Formato do @xlink:href:

    • Nome completo do arquivo (nome + extensão)
    • Arquivo deve estar no pacote do documento
  5. Consistência mime-type e mime-subtype:

    • video + mp4
    • audio + mp3
    • application + zip, pdf, xlsx, docx, pptx, etc.
  6. Acessibilidade (recomendado):

    • Vídeos e áudios devem ter <alt-text> e/ou <long-desc>
    • Transcrição do conteúdo em <sec sec-type="transcript">
    • Referência cruzada para transcrição usando <xref ref-type="sec">
  7. Restrições de uso:

    • Não usar <media> ou <inline-media> para figuras e imagens estáticas (usar <graphic> e <inline-graphic>)

Regras a Implementar

P0 – Críticas (implementar obrigatoriamente)

# Regra Nível Descrição
1 Validar presença de @id CRITICAL O atributo @id é obrigatório em <media> e <inline-media>
2 Validar presença de @mime-type CRITICAL O atributo @mime-type é obrigatório em <media> e <inline-media>
3 Validar presença de @mime-subtype CRITICAL O atributo @mime-subtype é obrigatório em <media> e <inline-media>
4 Validar presença de @xlink:href CRITICAL O atributo @xlink:href é obrigatório em <media> e <inline-media>
5 Validar consistência mime-type e mime-subtype ERROR Combinação de @mime-type e @mime-subtype deve ser válida (ex: video/mp4, audio/mp3, application/pdf)
6 Validar extensões obrigatórias ERROR Para vídeo: mp4; para áudio: mp3; para compactado: zip

P1 – Importantes (implementar se possível)

# Regra Nível Descrição
7 Validar presença de acessibilidade para vídeo/áudio WARNING Vídeos e áudios devem ter <alt-text> ou <long-desc> como elementos filhos
8 Recomendar transcrição para vídeo/áudio INFO Vídeos e áudios devem ter referência para <sec sec-type="transcript">

P2 – Futuras (fora do escopo deste Issue)

# Regra Motivo de exclusão
9 Validar que arquivo existe no pacote Alta complexidade - requer acesso ao sistema de arquivos
10 Validar contra lista completa IANA Media Types Média complexidade - requer manutenção de lista externa grande

Arquivos a Criar/Modificar

Avaliar existentes (podem ter validações parciais):

  • packtools/sps/models/media.py ou similar – Verificar se modelo existe
  • packtools/sps/validation/media.py – Verificar validações existentes
  • packtools/sps/validation/rules/media_rules.json ou similar – Verificar configuração

Criar (se não existirem):

  • packtools/sps/models/media.py – Modelo de extração de dados
  • packtools/sps/validation/media.py – Validações
  • packtools/sps/validation/rules/media_rules.json – Configuração de níveis de erro
  • tests/sps/validation/test_media.py – Testes unitários

Referenciar (implementações similares):

  • packtools/sps/validation/graphic.py – Validação de atributos obrigatórios similar
  • packtools/sps/validation/utils.py – Funções auxiliares (build_response)

Exemplos de XML

XML Válido (deve passar sem erros):

<!-- Exemplo 1: Vídeo em material suplementar -->
<supplementary-material id="suppl1">
    <label>Supplementary material 1</label>
    <caption>
        <title>Video 1</title>
    </caption>
    <media id="m1" mimetype="video" mime-subtype="mp4" xlink:href="1234-5678-scie-58-e1043-md1.mp4"/>
</supplementary-material>

<!-- Exemplo 2: Planilha Excel em material suplementar -->
<supplementary-material id="suppl2">
    <label>Supplementary material 2</label>
    <caption>
        <title>Spreadsheet 1</title>
    </caption>
    <media id="m2" mimetype="application" mime-subtype="xlsx" xlink:href="1234-5678-scie-58-e1043-md2.xlsx"/>
</supplementary-material>

<!-- Exemplo 3: Áudio -->
<media id="m3" mimetype="audio" mime-subtype="mp3" xlink:href="1234-5678-scie-58-e1043-md3.mp3">
    <label>Audio 1</label>
    <caption>
        <title>Áudio: entrevista</title>
    </caption>
</media>

<!-- Exemplo 4: Vídeo com descrição e transcrição -->
<media id="m4" mimetype="video" mime-subtype="mp4" xlink:href="1234-5678-scie-58-e1043-md4.mp4">
    <label>Video 1</label>
    <caption>
        <title>Vídeo: malesuada vehicula</title>
    </caption>
    <attrib>Fonte: consectetur adipiscing elit</attrib>
    <long-desc>Descrição detalhada do objeto (acima de 120 caracteres)</long-desc>
    <xref ref-type="sec" rid="TR1"/>
</media>

<!-- Exemplo 5: PDF -->
<media id="m5" mimetype="application" mime-subtype="pdf" xlink:href="1234-5678-scie-58-e1043-md5.pdf">
    <label>Document 1</label>
    <caption>
        <title>Documento complementar</title>
    </caption>
</media>

<!-- Exemplo 6: Documento Word -->
<media id="m6" mimetype="application" mime-subtype="docx" xlink:href="1234-5678-scie-58-e1043-md6.docx"/>

<!-- Exemplo 7: Apresentação PowerPoint -->
<media id="m7" mimetype="application" mime-subtype="pptx" xlink:href="1234-5678-scie-58-e1043-md7.pptx"/>

<!-- Exemplo 8: Arquivo compactado -->
<media id="m8" mimetype="application" mime-subtype="zip" xlink:href="1234-5678-scie-58-e1043-md8.zip"/>

<!-- Exemplo 9: inline-media em parágrafo -->
<p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
    <inline-media id="im1" mimetype="application" mime-subtype="pdf" xlink:href="1234-5678-scie-58-e1043-md9.pdf">Document</inline-media>
    elit erat malesuada magna.
</p>

<!-- Exemplo 10: Vídeo com alt-text -->
<media id="m10" mimetype="video" mime-subtype="mp4" xlink:href="1234-5678-scie-58-e1043-md10.mp4">
    <alt-text>Descrição breve do vídeo</alt-text>
</media>

XML Inválido – Caso 1: sem @id (CRITICAL)

<supplementary-material id="suppl1">
    <media mimetype="video" mime-subtype="mp4" xlink:href="video.mp4"/>
</supplementary-material>

Erro esperado: Atributo @id é obrigatório em <media>

XML Inválido – Caso 2: sem @mime-type (CRITICAL)

<supplementary-material id="suppl1">
    <media id="m1" mime-subtype="mp4" xlink:href="video.mp4"/>
</supplementary-material>

Erro esperado: Atributo @mime-type é obrigatório em <media>

XML Inválido – Caso 3: sem @mime-subtype (CRITICAL)

<supplementary-material id="suppl1">
    <media id="m1" mimetype="video" xlink:href="video.mp4"/>
</supplementary-material>

Erro esperado: Atributo @mime-subtype é obrigatório em <media>

XML Inválido – Caso 4: sem @xLink:href (CRITICAL)

<supplementary-material id="suppl1">
    <media id="m1" mimetype="video" mime-subtype="mp4"/>
</supplementary-material>

Erro esperado: Atributo @xlink:href é obrigatório em <media>

XML Inválido – Caso 5: sem @id (CRITICAL)

<p>
    Texto com <inline-media mimetype="application" mime-subtype="pdf" xlink:href="doc.pdf">documento</inline-media> inline.
</p>

Erro esperado: Atributo @id é obrigatório em <inline-media>

XML Inválido – Caso 6: Vídeo com extensão errada (ERROR)

<media id="m1" mimetype="video" mime-subtype="avi" xlink:href="video.avi"/>

Erro esperado: Para vídeo (@mime-type="video"), use @mime-subtype="mp4". Valor encontrado: avi

XML Inválido – Caso 7: Áudio com extensão errada (ERROR)

<media id="m1" mimetype="audio" mime-subtype="wav" xlink:href="audio.wav"/>

Erro esperado: Para áudio (@mime-type="audio"), use @mime-subtype="mp3". Valor encontrado: wav

XML Inválido – Caso 8: Compactado com extensão errada (ERROR)

<media id="m1" mimetype="application" mime-subtype="rar" xlink:href="files.rar"/>

Erro esperado: Para arquivos compactados, use @mime-subtype="zip". Valor encontrado: rar

XML Inválido – Caso 9: Inconsistência mime-type e mime-subtype (ERROR)

<media id="m1" mimetype="video" mime-subtype="pdf" xlink:href="document.pdf"/>

Erro esperado: Inconsistência entre @mime-type="video" e @mime-subtype="pdf". Para PDF, use @mime-type="application"

XML Inválido – Caso 10: @mime-type inválido (ERROR)

<media id="m1" mimetype="document" mime-subtype="pdf" xlink:href="doc.pdf"/>

Erro esperado: Valor "document" não é válido para @mime-type. Valores comuns: application, video, audio

XML Inválido – Caso 11: Atributos vazios (CRITICAL)

<media id="" mimetype="" mime-subtype="" xlink:href=""/>

Erro esperado: Atributos obrigatórios não podem estar vazios

XML Inválido – Caso 12: Vídeo sem alt-text ou long-desc (WARNING)

<media id="m1" mimetype="video" mime-subtype="mp4" xlink:href="video.mp4">
    <label>Video 1</label>
    <caption>
        <title>Vídeo sem descrição</title>
    </caption>
</media>

Erro esperado: Para acessibilidade, vídeos devem ter <alt-text> ou <long-desc> como elementos filhos

XML Inválido – Caso 13: Áudio sem alt-text ou long-desc (WARNING)

<media id="m1" mimetype="audio" mime-subtype="mp3" xlink:href="audio.mp3">
    <label>Audio 1</label>
</media>

Erro esperado: Para acessibilidade, áudios devem ter <alt-text> ou <long-desc> como elementos filhos

XML Inválido – Caso 14: @xLink:href sem extensão (ERROR)

<media id="m1" mimetype="video" mime-subtype="mp4" xlink:href="video"/>

Erro esperado: @xlink:href deve conter nome completo do arquivo incluindo extensão

XML Inválido – Caso 15: Extensão em xlink:href inconsistente com mime-subtype (ERROR)

<media id="m1" mimetype="video" mime-subtype="mp4" xlink:href="video.avi"/>

Erro esperado: Extensão do arquivo em @xlink:href (avi) não corresponde ao @mime-subtype (mp4)


Padrão de Implementação

Diretrizes Gerais:

  1. Seguir padrões existentes no repositório:

    • Consultar implementações similares como graphic.py (validação de atributos obrigatórios)
    • Usar estrutura de classes já estabelecida no packtools
    • IMPORTANTE: Verificar se já existem validações parciais para <media> e <inline-media> e integrá-las ou complementá-las
  2. Internacionalização (i18n):

    • OBRIGATÓRIO: Todas as mensagens devem suportar internacionalização
    • Usar advice_text e advice_params em build_response()
    • Consultar conversas anteriores sobre implementação de i18n no packtools
    • Referência: validações em article_contribs.py que já implementam i18n completo
  3. Validações condicionais:

    • Validações que dependem de contexto devem retornar None quando não aplicável
    • Exemplo: validação de extensões específicas só se aplica para mime-types específicos
    • Exemplo: validação de acessibilidade só para video/audio
    • Usar filter_results() nos testes para remover None
  4. Uso de build_response():

    • Sempre usar parent=self.data (dict completo, nunca string)
    • Campo response deve conter: "OK", "WARNING", "ERROR", "CRITICAL"
    • Sempre fornecer advice_text e advice_params para i18n
  5. Modelo de dados:

    • Criar propriedades separadas para media_elements e inline_media_elements
    • Cada dict deve conter: id, mime_type, mime_subtype, xlink_href, has_alt_text, has_long_desc, has_transcript_ref, parent, parent_id, parent_lang
  6. Validação de consistência mime-type e mime-subtype:

    • Criar mapeamento de combinações válidas:
      • videomp4
      • audiomp3
      • applicationpdf, xlsx, docx, pptx, zip, etc.
    • Alertar sobre inconsistências óbvias (ex: video/pdf)
  7. Extração de extensão:

    • Extrair extensão de @xlink:href usando os.path.splitext()
    • Comparar com @mime-subtype
    • Normalizar para lowercase antes de comparar
  8. Validação de acessibilidade:

    • Verificar presença de <alt-text> ou <long-desc> como filhos diretos
    • Aplicar apenas para @mime-type="video" ou @mime-type="audio"
    • Verificar presença de <xref ref-type="sec"> referenciando transcrição

Testes Esperados

Casos de teste obrigatórios:

Atributos obrigatórios em :

  • <media> com todos os atributos obrigatórios (OK)
  • <media> sem @id (CRITICAL)
  • <media> sem @mime-type (CRITICAL)
  • <media> sem @mime-subtype (CRITICAL)
  • <media> sem @xlink:href (CRITICAL)
  • Atributos vazios (CRITICAL)
  • Atributos apenas com espaços (CRITICAL)

Atributos obrigatórios em :

  • <inline-media> com todos os atributos obrigatórios (OK)
  • <inline-media> sem @id (CRITICAL)
  • <inline-media> sem @mime-type (CRITICAL)
  • <inline-media> sem @mime-subtype (CRITICAL)
  • <inline-media> sem @xlink:href (CRITICAL)

Valores de @mime-type:

  • @mime-type="video" (OK)
  • @mime-type="audio" (OK)
  • @mime-type="application" (OK)
  • @mime-type="text" (OK - permitir outros valores IANA)
  • @mime-type="image" (OK - mas WARNING sugerindo usar )
  • @mime-type="invalid" (ERROR)

Extensões obrigatórias:

  • Vídeo com mp4 (OK)
  • Vídeo com avi (ERROR)
  • Vídeo com mov (ERROR)
  • Vídeo com wmv (ERROR)
  • Áudio com mp3 (OK)
  • Áudio com wav (ERROR)
  • Áudio com ogg (ERROR)
  • Compactado application/zip (OK)
  • Compactado application/rar (ERROR)
  • Compactado application/7z (ERROR)

Consistência mime-type e mime-subtype:

  • video/mp4 (OK)
  • audio/mp3 (OK)
  • application/pdf (OK)
  • application/xlsx (OK)
  • application/docx (OK)
  • application/pptx (OK)
  • video/pdf (ERROR - inconsistente)
  • audio/xlsx (ERROR - inconsistente)
  • application/mp4 (WARNING - possível erro)

Consistência xlink:href e mime-subtype:

  • mp4 em href com mime-subtype="mp4" (OK)
  • mp4 em href com mime-subtype="avi" (ERROR)
  • pdf em href com mime-subtype="pdf" (OK)
  • Arquivo sem extensão (ERROR)
  • Case-insensitive .MP4 vs mp4 (OK)

Acessibilidade para vídeo/áudio:

  • Vídeo com <alt-text> (OK)
  • Vídeo com <long-desc> (OK)
  • Vídeo com ambos (OK)
  • Vídeo sem nenhum (WARNING)
  • Áudio com <alt-text> (OK)
  • Áudio sem <alt-text> nem <long-desc> (WARNING)
  • PDF sem <alt-text> (OK - não requerido para documentos)

Referência a transcrição:

  • Vídeo com <xref ref-type="sec"> (OK)
  • Vídeo sem referência a transcrição (INFO)
  • Áudio com referência a transcrição (OK)

Casos de borda:

  • Múltiplos <media> no mesmo documento (OK)
  • <media> aninhado em diferentes contextos (OK)
  • Arquivo com nome longo (OK)
  • Arquivo com caracteres especiais no nome (OK)
  • Extensões com diferentes cases .MP4, .Mp4 (OK - normalizar)

Total esperado: ~55 testes unitários

Estrutura de testes:

  • Usar filter_results() para remover None dos resultados
  • Asserções devem usar campo response (não is_valid)
  • Testes devem ser autocontidos e descritivos
  • Agrupar testes por categoria (atributos, mime-types, extensões, acessibilidade)
  • Testar ambos <media> e <inline-media> separadamente

Critérios de Aceite

O PR será aceito quando:

  • Verificação de validações existentes: Código existente para <media> e <inline-media> foi analisado e integrado ou substituído adequadamente
  • Todas as regras P0 implementadas (6 validações CRITICAL/ERROR)
  • Todas as regras P1 implementadas (2 validações WARNING/INFO)
  • Testes unitários passando com cobertura mínima de ~55 casos
  • Nenhum teste existente quebrado
  • Arquivo media_rules.json criado com todos os níveis de erro
  • Internacionalização completa em todas as mensagens (i18n obrigatório)
  • Código seguindo padrões do packtools (build_response, filter_results, validações condicionais)
  • Modelo de dados criado com extração adequada para ambos elementos
  • Validação de consistência mime-type/mime-subtype funcionando
  • Validação de extensões obrigatórias funcionando
  • Validação de acessibilidade para video/audio funcionando
  • Comparação de extensão em xlink:href com mime-subtype
  • Documentação inline clara (docstrings)

Referências

Documentação SPS:

Padrões JATS:

Padrões externos:

Acessibilidade:

Referências internas packtools:

  • Internacionalização: Consultar conversas anteriores sobre implementação de i18n
  • Implementações similares: graphic.py (atributos obrigatórios)
  • Funções auxiliares: utils.py (build_response)

Labels Sugeridas

enhancement validation SPS-1.10 accessibility good-first-issue


Impacto Esperado

Antes:

  • Conformidade SPS 1.10 para <media> e <inline-media>: X% (verificar validações existentes)
  • Atributos obrigatórios podem estar ausentes
  • Extensões não padronizadas podem passar (avi, wav, rar, etc.)
  • Inconsistências entre mime-type e mime-subtype não detectadas
  • Problemas de acessibilidade em vídeos/áudios não alertados

Depois:

  • Conformidade SPS 1.10 para <media> e <inline-media>: 70% (7 de 10 regras)
  • Validação CRITICAL de atributos obrigatórios (@id, @mime-type, @mime-subtype, @xLink:href)
  • Validação ERROR de extensões padronizadas (mp4, mp3, zip)
  • Validação ERROR de consistência mime-type/mime-subtype
  • Validação WARNING de acessibilidade para vídeos e áudios
  • ~55 testes unitários garantindo qualidade
  • Internacionalização completa (PT/EN/ES)

Benefícios:

  • Melhora a qualidade dos XMLs SciELO
  • Garante padronização de formatos multimídia
  • Detecta inconsistências antes da publicação
  • Promove acessibilidade em conteúdo multimídia
  • Facilita reprodução consistente em diferentes plataformas
  • Reduz problemas de compatibilidade
  • Melhora experiência para usuários com tecnologias assistivas
  • Garante conformidade com WCAG para conteúdo multimídia
  • Facilita manutenção e depuração de XMLs

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions