Skip to content

Criar validações para os elementos <sub-article> e <front-stub> #1110

@Rossi-Luciano

Description

@Rossi-Luciano

Objetivo

Implementar validações para os elementos <sub-article> e <front-stub> conforme a especificação SPS 1.10 e Critérios SciELO Brasil, aumentando a conformidade de X% para 70% (7 de 10 regras).

Nota: Algumas validações para <sub-article> e <front-stub> podem já estar parcialmente implementadas no repositório. Este Issue visa reavaliar, complementar e garantir cobertura completa das regras SPS 1.10 e Critérios SciELO Brasil.


Contexto

O elemento <sub-article> indica um documento aninhado dentro de outro e é obrigatório para documentos traduzidos. Sub-artigos herdam metadados do documento pai, necessitando apenas do elemento <front-stub> sem <journal-meta> e <article-meta>. Validações corretas garantem presença de atributos obrigatórios, estrutura adequada de <front-stub>, e conformidade com requisitos de tradução.

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.subarticle

Regras principais conforme SPS 1.10 e Critérios SciELO Brasil:

  1. Ocorrência:

    • <sub-article> pode aparecer zero ou mais vezes em <article> e <sub-article>
  2. Uso obrigatório:

    • Obrigatório para documentos traduzidos
  3. Atributos obrigatórios em <sub-article>:

    • @article-type (obrigatório)
    • @id (obrigatório)
    • @xml:lang (obrigatório)
  4. Valores permitidos para @article-type:

    • translation - Tradução (obrigatório para documentos traduzidos)
    • reviewer-report - Parecer (revisão por pares)
    • article-commentary - Comentário
    • letter - Carta
    • reply - Resposta
  5. Elemento <front-stub> obrigatório:

    • <sub-article> deve conter <front-stub>
    • Proibido: <journal-meta> e <article-meta> (herdam do pai)
  6. Elementos obrigatórios em <front-stub>:

    • <contrib-group> (obrigatório)
    • <article-title> (obrigatório)
  7. Regra de PDF:

    • @article-type="translation": um PDF para cada idioma
    • Outros tipos: mesmo PDF, sem DOI próprio
  8. Regras específicas para translation:

    • Traduções devem ser enviadas junto com versão no idioma original
    • PMC/PubMed: inglês em <article>, outras traduções em <sub-article>
    • Incluir dados traduzidos: afiliação, resumo, palavras-chave, notas de autor
    • Afiliação não traduzida: usar <institution content-type="original">
    • <elocation-id>, DOI, <history>: só se diferentes do original
  9. Unicidade:

    • Cada <sub-article> deve ter @id único

Regras a Implementar

P0 – Críticas (implementar obrigatoriamente)

# Regra Nível Descrição
1 Validar presença de @article-type CRITICAL O atributo @article-type é obrigatório em <sub-article>
2 Validar presença de @id CRITICAL O atributo @id é obrigatório em <sub-article>
3 Validar presença de @xml:lang CRITICAL O atributo @xml:lang é obrigatório em <sub-article>
4 Validar valores permitidos de @article-type ERROR O valor de @article-type deve estar na lista de valores permitidos
5 Validar presença de <front-stub> CRITICAL O elemento <front-stub> é obrigatório em <sub-article>
6 Validar presença de <contrib-group> em <front-stub> CRITICAL O elemento <contrib-group> é obrigatório em <front-stub>
7 Validar presença de <article-title> em <front-stub> CRITICAL O elemento <article-title> é obrigatório em <front-stub>

P1 – Importantes (implementar se possível)

# Regra Nível Descrição
8 Validar ausência de <journal-meta> em <front-stub> ERROR O elemento <journal-meta> não deve aparecer em <front-stub> (metadados são herdados do documento pai)
9 Validar ausência de <article-meta> em <front-stub> ERROR O elemento <article-meta> não deve aparecer em <front-stub> (metadados são herdados do documento pai)
10 Validar unicidade de @id ERROR Cada <sub-article> deve ter um @id único

P2 – Futuras (fora do escopo deste Issue)

# Regra Motivo de exclusão
11 Validar que para PMC/PubMed inglês está em <article> Alta complexidade - requer contexto de indexação externa
12 Validar consistência de idioma entre @xml:lang e <article-categories> Média complexidade - requer análise cross-element
13 Validar que <elocation-id>, DOI, <history> só aparecem se diferentes do original Alta complexidade - requer comparação com documento pai
14 Validar presença de artigo original quando há translation Alta complexidade - requer análise de estrutura completa

Arquivos a Criar/Modificar

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

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

Criar (se não existirem):

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

Referenciar (implementações similares):

  • packtools/sps/validation/article_and_subarticles.py – Validação de article já existe
  • packtools/sps/validation/utils.py – Funções auxiliares (build_response)

Exemplos de XML

XML Válido (deve passar sem erros):

<!-- Exemplo 1: Tradução completa para português -->
<article article-type="research-article" xml:lang="en">
    <front>
        <journal-meta>
            <!-- metadados do periódico -->
        </journal-meta>
        <article-meta>
            <article-id pub-id-type="doi">10.1590/example</article-id>
            <title-group>
                <article-title>Technology transfer during the covid-19 pandemic</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Carneiro</surname>
                        <given-names>Tainá Ferreira</given-names>
                    </name>
                </contrib>
            </contrib-group>
            <abstract>
                <p>English abstract.</p>
            </abstract>
        </article-meta>
    </front>
    <body>
        <p>English content.</p>
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <front-stub>
            <title-group>
                <article-title>Transferência tecnológica durante a pandemia de covid-19</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Carneiro</surname>
                        <given-names>Tainá Ferreira</given-names>
                    </name>
                </contrib>
            </contrib-group>
            <abstract>
                <p>Resumo em português.</p>
            </abstract>
        </front-stub>
        <body>
            <p>Conteúdo em português.</p>
        </body>
    </sub-article>
</article>

<!-- Exemplo 2: Parecer (reviewer-report) -->
<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo do artigo -->
    </body>
    <sub-article article-type="reviewer-report" id="R1" xml:lang="en">
        <front-stub>
            <title-group>
                <article-title>Reviewer Report</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Smith</surname>
                        <given-names>John</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Review content.</p>
        </body>
    </sub-article>
</article>

<!-- Exemplo 3: Comentário (article-commentary) -->
<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="article-commentary" id="C1" xml:lang="en">
        <front-stub>
            <title-group>
                <article-title>Commentary on this article</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Jones</surname>
                        <given-names>Mary</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Commentary content.</p>
        </body>
    </sub-article>
</article>

<!-- Exemplo 4: Carta (letter) -->
<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="letter" id="L1" xml:lang="en">
        <front-stub>
            <title-group>
                <article-title>Letter regarding this article</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Brown</surname>
                        <given-names>Robert</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Letter content.</p>
        </body>
    </sub-article>
</article>

<!-- Exemplo 5: Resposta (reply) -->
<article article-type="letter" xml:lang="en">
    <front>
        <!-- metadados da carta -->
    </front>
    <body>
        <!-- conteúdo da carta -->
    </body>
    <sub-article article-type="reply" id="R1" xml:lang="en">
        <front-stub>
            <title-group>
                <article-title>Reply to the letter</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Author</surname>
                        <given-names>Original</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Reply content.</p>
        </body>
    </sub-article>
</article>

<!-- Exemplo 6: Múltiplas traduções -->
<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo em inglês -->
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <front-stub>
            <title-group>
                <article-title>Título em português</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo em português.</p>
        </body>
    </sub-article>
    <sub-article article-type="translation" id="S2" xml:lang="es">
        <front-stub>
            <title-group>
                <article-title>Título en español</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>García</surname>
                        <given-names>Carlos</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Contenido en español.</p>
        </body>
    </sub-article>
</article>

<!-- Exemplo 7: Sub-article aninhado -->
<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <front-stub>
            <title-group>
                <article-title>Título em português</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo em português.</p>
        </body>
        <sub-article article-type="letter" id="L1" xml:lang="pt">
            <front-stub>
                <title-group>
                    <article-title>Carta sobre o artigo</article-title>
                </title-group>
                <contrib-group>
                    <contrib contrib-type="author">
                        <name>
                            <surname>Leitor</surname>
                            <given-names>Um</given-names>
                        </name>
                    </contrib>
                </contrib-group>
            </front-stub>
            <body>
                <p>Conteúdo da carta.</p>
            </body>
        </sub-article>
    </sub-article>
</article>

XML Inválido – Caso 1: Sem @article-type (CRITICAL)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article id="S1" xml:lang="pt">
        <front-stub>
            <title-group>
                <article-title>Título</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Atributo @article-type é obrigatório em <sub-article>

XML Inválido – Caso 2: Sem @id (CRITICAL)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" xml:lang="pt">
        <front-stub>
            <title-group>
                <article-title>Título</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Atributo @id é obrigatório em <sub-article>

XML Inválido – Caso 3: Sem @xml:lang (CRITICAL)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" id="S1">
        <front-stub>
            <title-group>
                <article-title>Título</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Atributo @xml:lang é obrigatório em <sub-article>

XML Inválido – Caso 4: @article-type com valor inválido (ERROR)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translated" id="S1" xml:lang="pt">
        <front-stub>
            <title-group>
                <article-title>Título</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Valor "translated" não está na lista de valores permitidos para @article-type. Use translation para traduções.

XML Inválido – Caso 5: Sem (CRITICAL)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Elemento <front-stub> é obrigatório em <sub-article>

XML Inválido – Caso 6: Sem em (CRITICAL)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <front-stub>
            <title-group>
                <article-title>Título</article-title>
            </title-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Elemento <contrib-group> é obrigatório em <front-stub>

XML Inválido – Caso 7: Sem em (CRITICAL)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <front-stub>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Elemento <article-title> é obrigatório em <front-stub>

XML Inválido – Caso 8: com (ERROR)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <front-stub>
            <journal-meta>
                <!-- não deve aparecer -->
            </journal-meta>
            <title-group>
                <article-title>Título</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Elemento <journal-meta> não deve aparecer em <front-stub> (metadados são herdados do documento pai)

XML Inválido – Caso 9: com (ERROR)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <front-stub>
            <article-meta>
                <!-- não deve aparecer -->
            </article-meta>
            <title-group>
                <article-title>Título</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Elemento <article-meta> não deve aparecer em <front-stub> (metadados são herdados do documento pai)

XML Inválido – Caso 10: IDs duplicados (ERROR)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <front-stub>
            <title-group>
                <article-title>Título em português</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
    <sub-article article-type="translation" id="S1" xml:lang="es">
        <front-stub>
            <title-group>
                <article-title>Título en español</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>García</surname>
                        <given-names>Carlos</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Contenido.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Valor de @id duplicado em <sub-article>: "S1" (aparece 2 vezes)

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

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="" id="" xml:lang="">
        <front-stub>
            <title-group>
                <article-title>Título</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

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

XML Inválido – Caso 12: @article-type com uppercase (ERROR)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="Translation" id="S1" xml:lang="pt">
        <front-stub>
            <title-group>
                <article-title>Título</article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Valor de @article-type deve estar em minúsculas. Use translation ao invés de Translation

XML Inválido – Caso 13: vazio (CRITICAL)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <front-stub>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: <front-stub> está vazio. Deve conter pelo menos <contrib-group> e <article-title>

XML Inválido – Caso 14: vazio (CRITICAL)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <front-stub>
            <title-group>
                <article-title></article-title>
            </title-group>
            <contrib-group>
                <contrib contrib-type="author">
                    <name>
                        <surname>Silva</surname>
                        <given-names>João</given-names>
                    </name>
                </contrib>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Elemento <article-title> não pode estar vazio

XML Inválido – Caso 15: vazio (CRITICAL)

<article article-type="research-article" xml:lang="en">
    <front>
        <!-- metadados -->
    </front>
    <body>
        <!-- conteúdo -->
    </body>
    <sub-article article-type="translation" id="S1" xml:lang="pt">
        <front-stub>
            <title-group>
                <article-title>Título</article-title>
            </title-group>
            <contrib-group>
            </contrib-group>
        </front-stub>
        <body>
            <p>Conteúdo.</p>
        </body>
    </sub-article>
</article>

Erro esperado: Elemento <contrib-group> está vazio. Deve conter pelo menos um <contrib>


Padrão de Implementação

Diretrizes Gerais:

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

    • Consultar implementações similares como article_and_subarticles.py (validação de article)
    • Usar estrutura de classes já estabelecida no packtools
    • IMPORTANTE: Verificar se já existem validações parciais para <sub-article> 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 elementos em <front-stub> só se aplica se <front-stub> existir
    • 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 propriedade que retorna lista de dicionários (um para cada <sub-article>)
    • Cada dict deve conter: article_type, id, xml_lang, has_front_stub, has_contrib_group, has_article_title, has_journal_meta, has_article_meta, parent, parent_id, parent_lang
  6. Lista de valores permitidos:

    • Criar constante: SUB_ARTICLE_TYPES = ["translation", "reviewer-report", "article-commentary", "letter", "reply"]
  7. Validação de unicidade de IDs:

    • Coletar todos os valores de @id em <sub-article>
    • Detectar duplicatas usando set ou Counter
    • Reportar quais IDs estão duplicados
  8. Validação de elementos em <front-stub>:

    • Verificar presença de <contrib-group> usando XPath ou .find()
    • Verificar presença de <article-title> (pode estar dentro de <title-group>)
    • Verificar ausência de <journal-meta> e <article-meta>
  9. Validação de valores:

    • Comparação case-sensitive: valores devem estar em minúsculas
    • Trimmar espaços antes de validar
  10. Suporte a aninhamento:

    • <sub-article> pode conter outro <sub-article>
    • Validar todos os níveis de aninhamento

Testes Esperados

Casos de teste obrigatórios:

Atributos obrigatórios:

  • <sub-article> com todos os atributos (OK)
  • Sem @article-type (CRITICAL)
  • Sem @id (CRITICAL)
  • Sem @xml:lang (CRITICAL)
  • Atributos vazios (CRITICAL)
  • Atributos apenas com espaços (CRITICAL)

Valores de @article-type:

  • translation (OK)
  • reviewer-report (OK)
  • article-commentary (OK)
  • letter (OK)
  • reply (OK)
  • Valor inválido "translated" (ERROR)
  • Valor inválido "review" (ERROR)
  • Valor inválido "comment" (ERROR)
  • Uppercase "Translation" (ERROR)

Presença de :

  • <sub-article> com <front-stub> (OK)
  • <sub-article> sem <front-stub> (CRITICAL)
  • <front-stub> vazio (CRITICAL)

Elementos em :

  • <front-stub> com <contrib-group> (OK)
  • <front-stub> sem <contrib-group> (CRITICAL)
  • <contrib-group> vazio (CRITICAL)
  • <front-stub> com <article-title> (OK)
  • <front-stub> sem <article-title> (CRITICAL)
  • <article-title> vazio (CRITICAL)
  • <article-title> apenas espaços (CRITICAL)

Elementos proibidos em :

  • <front-stub> sem <journal-meta> (OK)
  • <front-stub> com <journal-meta> (ERROR)
  • <front-stub> sem <article-meta> (OK)
  • <front-stub> com <article-meta> (ERROR)

Unicidade de @id:

  • Um <sub-article> com ID único (OK)
  • Dois <sub-article> com IDs diferentes (OK)
  • Dois <sub-article> com mesmo ID (ERROR)
  • Três <sub-article> com IDs duplicados (ERROR)

Valores de @xml:lang:

  • @xml:lang="pt" (OK)
  • @xml:lang="en" (OK)
  • @xml:lang="es" (OK)
  • @xml:lang vazio (CRITICAL)

Múltiplos sub-articles:

  • Artigo sem <sub-article> (OK - zero ou mais)
  • Artigo com um <sub-article> (OK)
  • Artigo com dois <sub-article> (OK)
  • Artigo com três ou mais <sub-article> (OK)

Sub-article aninhado:

  • <sub-article> dentro de <sub-article> (OK)
  • Três níveis de aninhamento (OK)

Estrutura completa:

  • <sub-article> com <front-stub>, <body>, <back> (OK)
  • <sub-article> sem <body> (OK - body opcional)
  • <sub-article> sem <back> (OK - back opcional)

Casos de borda:

  • <sub-article> completamente vazio (CRITICAL)
  • <article-title> dentro de <title-group> (OK)
  • <article-title> fora de <title-group> (OK - ambos aceitos)
  • Múltiplos <contrib> em <contrib-group> (OK)

Total esperado: ~50 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, article-type, front-stub, unicidade)

Critérios de Aceite

O PR será aceito quando:

  • Verificação de validações existentes: Código existente para <sub-article> foi analisado e integrado ou substituído adequadamente
  • Todas as regras P0 implementadas (7 validações CRITICAL/ERROR)
  • Todas as regras P1 implementadas (3 validações ERROR)
  • Testes unitários passando com cobertura mínima de ~50 casos
  • Nenhum teste existente quebrado
  • Arquivo sub_article_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 de todos os sub-articles
  • Validação de atributos obrigatórios funcionando
  • Validação de valores permitidos de @article-type funcionando
  • Validação de elementos obrigatórios em <front-stub> funcionando
  • Validação de ausência de <journal-meta> e <article-meta> funcionando
  • Validação de unicidade de IDs funcionando
  • Suporte para sub-articles aninhados
  • Documentação inline clara (docstrings)

Referências

Documentação SPS:

Critérios SciELO Brasil:

Padrões JATS:

Referências internas packtools:

  • Internacionalização: Consultar conversas anteriores sobre implementação de i18n
  • Implementações similares: article_and_subarticles.py (validação de article)
  • Funções auxiliares: utils.py (build_response)

Labels Sugeridas

enhancement validation SPS-1.10 scielo-brasil good-first-issue


Impacto Esperado

Antes:

  • Conformidade SPS 1.10 para <sub-article>: X% (verificar validações existentes)
  • Atributos obrigatórios podem estar ausentes
  • Valores incorretos de @article-type podem passar
  • <front-stub> pode estar ausente ou incompleto
  • <journal-meta> e <article-meta> podem aparecer incorretamente
  • IDs duplicados podem não ser detectados
  • Elementos obrigatórios podem estar ausentes

Depois:

  • Conformidade SPS 1.10 para <sub-article>: 70% (7 de 10 regras)
  • Validação CRITICAL de atributos obrigatórios
  • Validação ERROR de valores permitidos de @article-type
  • Validação CRITICAL de presença de <front-stub>
  • Validação CRITICAL de elementos obrigatórios em <front-stub>
  • Validação ERROR de ausência de metadados que devem ser herdados
  • Validação ERROR de unicidade de IDs
  • ~50 testes unitários garantindo qualidade
  • Internacionalização completa (PT/EN/ES)

Benefícios:

  • Garante conformidade com Critérios SciELO Brasil (tradução obrigatória)
  • Detecta ausência de atributos obrigatórios antes da publicação
  • Assegura estrutura correta de <front-stub> (sem metadados herdados)
  • Previne duplicação de IDs em sub-artigos
  • Melhora qualidade de documentos traduzidos
  • Facilita processamento de pareceres, cartas, comentários e respostas
  • Garante presença de informações essenciais (título, autores)
  • Evita redundância de metadados (herança do documento pai)
  • Facilita manutenção e depuração de XMLs

Observações importantes:

  • Implementar internacionalização ajustando as respostas das validações ao formato da função build_response em packtools/sps/validation/utils.py;
  • Verificar e adicionar as validações no orquestrador: packtools/sps/validation/xml_validations.py e packtools/sps/validation/xml_validator.py
  • Verificar a corretude dos testes exsitentes para a validação e complementar caso necessário;
  • Realizar ajustes, caso necessário, nos modelos que são utilizados pelas validações, garantindo que o ajuste não interfira em possíveis usos atuais desses modelos.

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