Skip to content

Add <xref> element validations per SPS 1.10 specification#1136

Draft
Copilot wants to merge 2 commits intomasterfrom
copilot/create-validations-for-xref-element
Draft

Add <xref> element validations per SPS 1.10 specification#1136
Copilot wants to merge 2 commits intomasterfrom
copilot/create-validations-for-xref-element

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 19, 2026

O que esse PR faz?

Implementa 7 das 10 regras de validação para o elemento <xref> conforme SPS 1.10 e Critérios SciELO Brasil (70% de conformidade).

P0 – Críticas:

  • validate_rid_presence (CRITICAL) — @rid obrigatório e não-vazio
  • validate_ref_type_presence (CRITICAL) — @ref-type obrigatório e não-vazio
  • validate_ref_type_value (ERROR) — @ref-type deve ser um dos 16 valores permitidos
  • validate_bibr_presence (ERROR) — ao menos um <xref ref-type="bibr"> no documento
  • validate_rid_has_corresponding_id (ERROR) — todo @rid deve ter @id correspondente

P1 – Importantes:

  • validate_transcript_xref (WARNING) — <sec sec-type="transcript"> precisa de <xref ref-type="sec">
  • validate_aff_self_closing (INFO) — <xref ref-type="aff"> sem texto deve usar formato self-closing

Corrige bugs no método existente validate_attrib_name_and_value_has_corresponding_xref() que usava self.xref_xml (inexistente) e o builtin id em vez da variável do loop.

Onde a revisão poderia começar?

packtools/sps/validation/article_xref.py — contém todas as novas validações e as correções nos métodos existentes.

Como este poderia ser testado manualmente?

from lxml import etree
from packtools.sps.validation.article_xref import ArticleXrefValidation

xml = etree.fromstring('''
<article article-type="research-article" xml:lang="pt">
  <body>
    <p><xref ref-type="bibr" rid="B1">1</xref></p>
    <p><xref ref-type="image" rid="f1">Figure 1</xref></p>
    <p><xref ref-type="fig">Figure 2</xref></p>
  </body>
  <back>
    <ref-list><ref id="B1"><mixed-citation>Ref</mixed-citation></ref></ref-list>
  </back>
</article>
''')

v = ArticleXrefValidation(xml)
for r in v.validate_rid_presence():
    print(r["response"])      # OK, OK, CRITICAL (missing rid)
for r in v.validate_ref_type_value():
    print(r["response"])      # OK, ERROR ("image" invalid), skipped (empty)
for r in v.validate_bibr_presence():
    print(r["response"])      # OK

74 testes unitários: python -m pytest tests/sps/validation/test_article_xref.py -v

Algum cenário de contexto que queira dar?

Validações parciais para <xref> já existiam (validate_xref_rid_has_corresponding_element_id, validate_element_id_has_corresponding_xref_rid, validate_attrib_name_and_value_has_corresponding_xref). Este PR complementa com as regras faltantes e corrige bugs nos métodos existentes. Os testes existentes foram reescritos para o formato atual com suporte a i18n (msg_text, msg_params, adv_text, adv_params).

Arquivos alterados:

  • packtools/sps/validation_rules/xref_rules.json — novo arquivo de configuração de regras
  • packtools/sps/models/v2/article_xref.pyall_xrefs(), all_ids(), transcript_sections() em XMLCrossReference
  • packtools/sps/validation/article_xref.py — 7 novos métodos + correção de bugs
  • packtools/sps/validation/xml_validations.py — orquestrador atualizado
  • tests/sps/validation/test_article_xref.py — 74 testes em 14 classes

Screenshots

N/A

Quais são tickets relevantes?

Referências

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.crossref.org
    • Triggering command: /usr/bin/python python -m pytest tests/sps/validation/ -v --ignore=tests/sps/validation/test_footnotes.py (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Criar validações para o elemento </issue_title>
<issue_description>## Objetivo

Implementar validações para o elemento <xref> 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 <xref> 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 <xref> é usado para referência cruzada relacionando informações no texto. Para SciELO Brasil, é obrigatória a presença de pelo menos uma <xref> com @ref-type="bibr" (referência bibliográfica) no documento. Validações corretas garantem presença de atributos obrigatórios, valores válidos, e correspondência entre @rid e @id.

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

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

  1. Ocorrência:

    • <xref> pode aparecer zero ou mais vezes em: <article-title>, <attrib>, <contrib>, <p>, <td>, <th>, <trans-title>, <sec>, <verse-line>
  2. Obrigatoriedade (Critério SciELO Brasil):

    • <xref> com @ref-type="bibr" deve ocorrer pelo menos uma vez no documento
  3. Atributos obrigatórios:

    • @rid - Contém identificador do elemento referenciado (obrigatório)
    • @ref-type - Especifica tipo de referência cruzada (obrigatório)
  4. Valores permitidos para @ref-type:

    • aff - Afiliação
    • app - Apêndice
    • author-notes - Notas relacionadas ao autor
    • bibr - Referência bibliográfica
    • bio - Bibliografia do autor
    • boxed-text - Caixa de texto
    • contrib - Autoria
    • corresp - Autor correspondente
    • disp-formula - Fórmula/Equação
    • fig - Figura ou grupo de figuras
    • fn - Nota
    • list - Lista ou item da lista
    • sec - Seção
    • supplementary-material - Material suplementar
    • table - Tabela ou grupo de tabelas
    • table-fn - Nota de rodapé de tabelas
  5. Correspondência @rid e @id:

    • Todo @rid obrigatoriamente deve ter @id correspondente no XML
    • Um @id pode ou não ter @rid correspondente
  6. Regra especial para transcrição:

    • <xref ref-type="sec" @rid> é obrigatório quando existe <sec sec-type="transcript">
  7. Regra especial para afiliação:

    • Para afiliação sem identificação de etiqueta no PDF: usar <xref ref-type="aff" rid="aff1"/> (self-closing)
  8. Regra de <sup>:

    • <sup> não pode abarcar <xref> quando não há caracteres textuais
    • Neste caso <sup> deve estar dentro de <xref>
  9. Menção obrigatória:

    • Para valores exceto aff, deve ocorrer menção ou etiqueta correspondente no texto

Regras a Implementar

P0 – Críticas (implementar obrigatoriamente)

# Regra Nível Descrição
1 Validar presença de @rid CRITICAL O atributo @rid é obrigatório em <xref>
2 Validar presença de @ref-type CRITICAL O atributo @ref-type é obrigatório em <xref>
3 Validar valores permitidos de @ref-type ERROR O valor de @ref-type deve estar na lista de valores permitidos
4 Validar presença de pelo menos um @ref-type="bibr" ERROR Documento deve conter pelo menos uma <xref> com @ref-type="bibr" (Critério SciELO Brasil)
5 Validar correspondência @rid e @id ERROR Todo @rid em <xref> deve ter @id correspondente no documento

P1 – Importantes (implementar se possível)

# Regra Nível Descrição
6 Validar presença de <xref> para transcrição WARNING Quando há <sec sec-type="transcript">, deve haver <xref ref-type="sec"> referenciando-a
7 Validar formato de afiliação sem label INFO Para @ref-type="aff" sem conteúdo textual, recomenda-se usar elemento self-closing <xref ... />

P2 – Futuras (fora do escopo deste Issue)

# Regra Motivo de exclusão
8 Validar que <sup> não abarca <xref> sem texto Alta complexidade - requer análise de estrutura e conteúdo textual
9 Validar presença de menção/etiqueta no texto Alta complexidade - requer análise semântica do texto
10 Validar formatação consistente de citações Baixa prioridade - formato livre permitido

Arquivos a Criar/Modificar

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

  • packtools/sps/models/xref.py ou similar – Verificar se modelo existe
  • packtools/sps/validation/xref.py – Verificar validações existentes
  • `packtools/sps/validation/rules/xref_rul...

📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.

…pe values, bibr presence, rid-id correspondence, transcript xref, aff self-closing

Co-authored-by: robertatakenaka <505143+robertatakenaka@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement validations for the <xref> element Add <xref> element validations per SPS 1.10 specification Mar 19, 2026
Copilot AI requested a review from robertatakenaka March 19, 2026 12:05
Copy link
Copy Markdown
Collaborator

@Rossi-Luciano Rossi-Luciano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Evidência de revisão -- article_xref.py

Data: 2026-04-24
Revisor: Luciano
Artefatos analisados:

  • article_xref.py (validation) -- módulo de validação (ArticleXrefValidation)
  • article_xref.py (model, models/v2/) -- XMLCrossReference, Xref, Element
  • xref_rules.json -- parâmetros de configuração
  • article_xref.xml -- XML artificial gerado para cobertura de testes
  • article_xref-2026-24-04-114300-errors.csv -- relatório de erros gerado pelo packtools

Metodologia

Análise cruzada entre os dois módulos de mesmo nome (article_xref.py de validation
e de models/v2), o JSON de regras, o XML artificial construído com o princípio do
defeito isolado, e o relatório CSV. Para cada caso documentado no XML verificou-se:
se o método de validação deveria disparar o erro (leitura do código), se o CSV contém
a entrada correspondente, se o nível de severidade está correto, e se casos válidos
estão corretamente ausentes do CSV. O model foi necessário para confirmar três pontos:
(1) distinção entre all_ids() e elems_by_id("*") usados em R5 e R6, (2) cálculo
de has_text_content para R10, e (3) como elems_by_id(attribs=[...]) filtra por
atributo para R8.


Regras validadas (10 métodos)

# Método Nível configurado
R1 validate_rid_presence CRITICAL
R2 validate_ref_type_presence CRITICAL
R3 validate_ref_type_value ERROR
R4 validate_bibr_presence ERROR
R5 validate_rid_has_corresponding_id ERROR
R6 validate_xref_rid_has_corresponding_element_id ERROR
R7 validate_element_id_has_corresponding_xref_rid ERROR
R8 validate_attrib_name_and_value_has_corresponding_xref CRITICAL
R9 validate_transcript_xref WARNING
R10 validate_aff_self_closing INFO

Casos de teste no XML artificial

Caso Defeito introduzido Nível esperado Isolamento
P1 Nenhum -- caso ouro completo OK (ausente do CSV) aff1, f01, B01 com xrefs corretas
C-R1 <xref ref-type="fig"> sem @Rid CRITICAL R6 não dispara: elements_by_id[None] é não-vazio
C-R2 <xref rid="B01"> sem @ref-type CRITICAL rid="B01" existe; R5/R6 passam
C-R3 <xref ref-type="invalid-type" rid="B01"> ERROR rid="B01" existe; R5/R6 passam
C-R4* não testável neste XML ERROR requer ausência total de xref ref-type="bibr"
C-R5/R6 <xref ref-type="fig" rid="fig-inexistente"> ERROR + ERROR ambas as regras disparam para a mesma xref (cascata esperada)
C-R7 <fig id="f-orphan"> sem xref correspondente ERROR nenhuma xref com rid="f-orphan" no documento
C-R8 + C-R9a <sec sec-type="transcript" id="s-trans1"> sem xref algum CRITICAL + WARNING cascata: R8 verifica existência de xref, R9 verifica ref-type="sec"
C-R9b <sec sec-type="transcript" id="s-trans2"> + <xref ref-type="fn" rid="s-trans2"> WARNING R8 PASS (xref existe); R9 WARNING (fn != sec)
C-R10 <xref ref-type="aff" rid="aff1"></xref> (vazio) INFO has_text_content=False; aff1 ainda tem xref com texto (P1) portanto R7 passa

Verificação cruzada com o CSV

Todas as 10 entradas esperadas do módulo article_xref.py (validation) aparecem
no CSV sob o subject id and rid, com os níveis de severidade corretos:

Linha CSV Caso Nível Verificação
id and rid C-R1 CRITICAL PASS -- "Provide a valid @Rid attribute for xref"
id and rid C-R2 CRITICAL PASS -- "Provide a valid @ref-type attribute for xref"
id and rid C-R3 ERROR PASS -- "Replace invalid-type with one of the allowed values"
id and rid C-R5 ERROR PASS -- "@Rid=fig-inexistente has no corresponding @id in the document"
id and rid C-R6 ERROR PASS -- "Found xref rid=fig-inexistente, but not found the corresponding fig"
id and rid C-R7 ERROR PASS -- "Found fig id=f-orphan, but no corresponding xref was found"
id and rid C-R8 CRITICAL PASS -- "Found sec sec-type=transcript id=s-trans1, but no corresponding xref"
id and rid C-R9a WARNING PASS -- "Add xref ref-type=sec rid=s-trans1 to reference the transcript section"
id and rid C-R9b WARNING PASS -- "Add xref ref-type=sec rid=s-trans2 to reference the transcript section"
id and rid C-R10 INFO PASS -- "For ref-type=aff without text content, use self-closing"

R4 (validate_bibr_presence) não aparece no CSV (is_valid=True; xref ref-type="bibr"
presente para B01). O caso ouro P1 não gera nenhuma entrada. Não foram identificados
falsos positivos nem falsos negativos originados do módulo.


Ruído identificado (outros módulos) -- 38 entradas

Ruído estrutural (XML artificial mínimo sem abstract, history, subject etc.):
abstract ausente, history dates ausentes (received, rev-request, rev-recd, accepted, pub),
subj-group heading ausente, disp-formula/inline-formula/table-wrap ausentes, app ausente,
open science statement ausente.

Ruído de ambiente: rendition PDF ausente, DOI não registrado no Crossref, issue não
verificada no Core.

Ruído da estrutura de afiliação (aff): a afiliação de teste é mínima (apenas institution
text); o validador de aff exige label, institution content-type original/orgname/orgdiv1,
country com código ISO, addr-line com state e city (9 entradas).

Ruído de contrib: o contrib no XML não tem <n> nem role, gerando 3x CRITICAL.

Novos tipos de ruído identificados nesta sessão (incorporados ao padrão):

  1. <graphic xlink:href="...">: arquivos f01.jpg e f-orphan.jpg geram 2x CRITICAL
    "file not present in package". Para próximos XMLs: omitir <graphic> ou omitir
    o atributo xlink:href.
  2. <graphic> sem @id: 2x CRITICAL "Add id= to graphic". Adicionar @id a todos os
    elementos graphic.
  3. <graphic> sem <alt-text>: 2x WARNING accessibility. Adicionar alt-text ou
    omitir graphic.

Conclusão

O módulo article_xref.py (validation) está correto. Todas as 10 entradas
esperadas dispararam com os níveis de severidade corretos, sem falsos positivos nem
falsos negativos originados do módulo. R4 passou corretamente (bibr presente). A
regra R4 requer XML separado para teste do caso negativo (ausência total de bibr xrefs).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Criar validações para o elemento <xref>

3 participants