-
Notifications
You must be signed in to change notification settings - Fork 3
Implementa processamento de author-notes para elementos corresp #128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementa processamento de author-notes para elementos corresp #128
Conversation
- Cria nova classe XMLArticleMetaAuthorNotesPipe - Move elementos corresp de back/body para author-notes - Posiciona author-notes como irmão de contrib-group - Implementa precondição para verificar existência de corresp
- Importa XMLArticleMetaAuthorNotesPipe - Adiciona pipe após XMLArticleMetaContribGroupPipe no processo - Mantém ordem lógica de processamento dos metadados do artigo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements a new pipeline component (XMLArticleMetaAuthorNotesPipe) to restructure XML documents according to SPS (SciELO Publishing Schema) specifications. The pipe automatically moves <corresp> elements that appear in incorrect locations (<back> or <body>) to their proper semantic location within an <author-notes> element inside <article-meta>.
Key Changes:
- New
XMLArticleMetaAuthorNotesPipeclass to process and relocate correspondence elements - Integration into the main processing pipeline after
XMLArticleMetaContribGroupPipe - Precondition logic to execute only when
<corresp>elements are present
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
scielo_classic_website/spsxml/sps_xml_pipes.py |
Adds import and instantiation of XMLArticleMetaAuthorNotesPipe in the processing pipeline |
scielo_classic_website/spsxml/sps_xml_article_meta.py |
Implements the new XMLArticleMetaAuthorNotesPipe class with logic to identify, move, and reposition <corresp> elements |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| """ | ||
| Pipe para criar author-notes como irmão de contrib-group. | ||
| Move elementos corresp de back para dentro de author-notes. | ||
| Executa após XMLArticleMetacontribGroupPipe. |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in docstring: "XMLArticleMetacontribGroupPipe" should be "XMLArticleMetaContribGroupPipe" (capital C in "Contrib").
| Executa após XMLArticleMetacontribGroupPipe. | |
| Executa após XMLArticleMetaContribGroupPipe. |
| contrib_group = article_meta.find("contrib-group") | ||
|
|
||
| if contrib_group is not None: | ||
| # Insere author-notes após contrib-group | ||
| contrib_group_index = list(article_meta).index(contrib_group) | ||
| article_meta.insert(contrib_group_index + 1, author_notes) | ||
| else: | ||
| # Se não há contrib-group, adiciona ao final de article-meta | ||
| article_meta.append(author_notes) | ||
|
|
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential None reference error. If article_meta is None (when ./front/article-meta doesn't exist), calling article_meta.find("contrib-group") on line 314 will raise an AttributeError. Consider adding a null check: if article_meta is not None: before line 314, or handle the case when article-meta doesn't exist.
| contrib_group = article_meta.find("contrib-group") | |
| if contrib_group is not None: | |
| # Insere author-notes após contrib-group | |
| contrib_group_index = list(article_meta).index(contrib_group) | |
| article_meta.insert(contrib_group_index + 1, author_notes) | |
| else: | |
| # Se não há contrib-group, adiciona ao final de article-meta | |
| article_meta.append(author_notes) | |
| if article_meta is not None: | |
| contrib_group = article_meta.find("contrib-group") | |
| if contrib_group is not None: | |
| # Insere author-notes após contrib-group | |
| contrib_group_index = list(article_meta).index(contrib_group) | |
| article_meta.insert(contrib_group_index + 1, author_notes) | |
| else: | |
| # Se não há contrib-group, adiciona ao final de article-meta | |
| article_meta.append(author_notes) | |
| else: | |
| logging.warning("article-meta element not found; cannot insert author-notes.") |
| if corresp_elements: | ||
| # Cria author-notes | ||
| author_notes = ET.Element("author-notes") | ||
|
|
||
| # Move cada corresp para dentro de author-notes | ||
| for corresp in corresp_elements: | ||
| # Remove corresp de sua localização atual | ||
| parent = corresp.getparent() | ||
| if parent is not None: | ||
| parent.remove(corresp) | ||
|
|
||
| # Adiciona corresp ao author-notes | ||
| author_notes.append(corresp) | ||
|
|
||
| # Insere author-notes como irmão de contrib-group | ||
| article_meta = xml.find("./front/article-meta") | ||
| contrib_group = article_meta.find("contrib-group") | ||
|
|
||
| if contrib_group is not None: | ||
| # Insere author-notes após contrib-group | ||
| contrib_group_index = list(article_meta).index(contrib_group) | ||
| article_meta.insert(contrib_group_index + 1, author_notes) | ||
| else: | ||
| # Se não há contrib-group, adiciona ao final de article-meta | ||
| article_meta.append(author_notes) | ||
|
|
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant condition check. The if corresp_elements: check on line 298 is redundant since the precondition on lines 283-289 already ensures that corresp_elements is not empty. This check can be removed, and the code inside can be dedented.
| if corresp_elements: | |
| # Cria author-notes | |
| author_notes = ET.Element("author-notes") | |
| # Move cada corresp para dentro de author-notes | |
| for corresp in corresp_elements: | |
| # Remove corresp de sua localização atual | |
| parent = corresp.getparent() | |
| if parent is not None: | |
| parent.remove(corresp) | |
| # Adiciona corresp ao author-notes | |
| author_notes.append(corresp) | |
| # Insere author-notes como irmão de contrib-group | |
| article_meta = xml.find("./front/article-meta") | |
| contrib_group = article_meta.find("contrib-group") | |
| if contrib_group is not None: | |
| # Insere author-notes após contrib-group | |
| contrib_group_index = list(article_meta).index(contrib_group) | |
| article_meta.insert(contrib_group_index + 1, author_notes) | |
| else: | |
| # Se não há contrib-group, adiciona ao final de article-meta | |
| article_meta.append(author_notes) | |
| # Cria author-notes | |
| author_notes = ET.Element("author-notes") | |
| # Move cada corresp para dentro de author-notes | |
| for corresp in corresp_elements: | |
| # Remove corresp de sua localização atual | |
| parent = corresp.getparent() | |
| if parent is not None: | |
| parent.remove(corresp) | |
| # Adiciona corresp ao author-notes | |
| author_notes.append(corresp) | |
| # Insere author-notes como irmão de contrib-group | |
| article_meta = xml.find("./front/article-meta") | |
| contrib_group = article_meta.find("contrib-group") | |
| if contrib_group is not None: | |
| # Insere author-notes após contrib-group | |
| contrib_group_index = list(article_meta).index(contrib_group) | |
| article_meta.insert(contrib_group_index + 1, author_notes) | |
| else: | |
| # Se não há contrib-group, adiciona ao final de article-meta | |
| article_meta.append(author_notes) | |
| class XMLArticleMetaAuthorNotesPipe(plumber.Pipe): | ||
| """ | ||
| Pipe para criar author-notes como irmão de contrib-group. | ||
| Move elementos corresp de back para dentro de author-notes. | ||
| Executa após XMLArticleMetacontribGroupPipe. | ||
| """ | ||
|
|
||
| def precond(data): | ||
| raw, xml = data | ||
|
|
||
| # Verifica se existe corresp em back | ||
| corresp_elements = xml.xpath(".//back//corresp|.//body//corresp") | ||
| if not corresp_elements: | ||
| raise plumber.UnmetPrecondition() | ||
|
|
||
| @plumber.precondition(precond) | ||
| def transform(self, data): | ||
| raw, xml = data | ||
|
|
||
| # Encontra elementos corresp em back | ||
| corresp_elements = xml.xpath(".//back//corresp|.//body//corresp") | ||
|
|
||
| if corresp_elements: | ||
| # Cria author-notes | ||
| author_notes = ET.Element("author-notes") | ||
|
|
||
| # Move cada corresp para dentro de author-notes | ||
| for corresp in corresp_elements: | ||
| # Remove corresp de sua localização atual | ||
| parent = corresp.getparent() | ||
| if parent is not None: | ||
| parent.remove(corresp) | ||
|
|
||
| # Adiciona corresp ao author-notes | ||
| author_notes.append(corresp) | ||
|
|
||
| # Insere author-notes como irmão de contrib-group | ||
| article_meta = xml.find("./front/article-meta") | ||
| contrib_group = article_meta.find("contrib-group") | ||
|
|
||
| if contrib_group is not None: | ||
| # Insere author-notes após contrib-group | ||
| contrib_group_index = list(article_meta).index(contrib_group) | ||
| article_meta.insert(contrib_group_index + 1, author_notes) | ||
| else: | ||
| # Se não há contrib-group, adiciona ao final de article-meta | ||
| article_meta.append(author_notes) | ||
|
|
||
| return data |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing test coverage for XMLArticleMetaAuthorNotesPipe. The repository has comprehensive test coverage for similar pipes (e.g., XMLArticleMetaAffiliationPipe, XMLArticleMetaPublicationDatesPipe) in tests/test_sps_xml_article_meta.py. Consider adding test cases that cover:
- Moving
<corresp>elements from<back>to<author-notes> - Moving
<corresp>elements from<body>to<author-notes> - Correct positioning after
<contrib-group> - Fallback behavior when no
<contrib-group>exists - Precondition behavior (pipe should not execute when no
<corresp>elements exist)
| def precond(data): | ||
| raw, xml = data | ||
|
|
||
| # Verifica se existe corresp em back |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inaccurate comment. The comment says "Verifica se existe corresp em back" (Checks if corresp exists in back), but the XPath also checks for corresp in body (".//back//corresp|.//body//corresp"). Update the comment to: "Verifica se existe corresp em back ou body".
| # Verifica se existe corresp em back | |
| # Verifica se existe corresp em back ou body |
| def transform(self, data): | ||
| raw, xml = data | ||
|
|
||
| # Encontra elementos corresp em back |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inaccurate comment. The comment says "Encontra elementos corresp em back" (Finds corresp elements in back), but the XPath also finds corresp in body (".//back//corresp|.//body//corresp"). Update the comment to: "Encontra elementos corresp em back ou body".
| # Encontra elementos corresp em back | |
| # Encontra elementos corresp em back ou body |
| # Cria author-notes | ||
| author_notes = ET.Element("author-notes") |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing handling for existing <author-notes> element. The code always creates a new <author-notes> element (line 300), but if an <author-notes> element already exists in <article-meta>, this would create a duplicate. Consider checking if <author-notes> already exists and either:
- Append
<corresp>elements to the existing<author-notes>, or - Document that this pipe assumes no pre-existing
<author-notes>element.
Example check:
author_notes = article_meta.find("author-notes")
if author_notes is None:
author_notes = ET.Element("author-notes")
# ... positioning logic| Executa após XMLArticleMetacontribGroupPipe. | ||
| """ | ||
|
|
||
| def precond(data): |
Copilot
AI
Dec 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normal methods should have 'self', rather than 'data', as their first parameter.
| def precond(data): | |
| def precond(self, data): |
Pull Request: Implementa processamento de author-notes para elementos corresp
📋 Descrição
Implementa novo pipe para processar elementos
<corresp>localizados em<back>ou<body>, movendo-os para dentro de<author-notes>na seção<article-meta>, conforme especificação SPS para estruturação de metadados de correspondência de autores.🎯 Motivação
Elementos de correspondência (
<corresp>) frequentemente aparecem em seções inadequadas do XML (back/body), mas segundo o padrão SPS devem estar organizados dentro de<author-notes>em<article-meta>para melhor estruturação semântica e processamento padronizado.✨ Alterações Implementadas
Nova funcionalidade
<corresp>em<back>ou<body><author-notes><corresp>para dentro de<author-notes><author-notes>como irmão imediato após<contrib-group>Integração ao pipeline
XMLArticleMetaContribGroupPipe🔄 Exemplo de Transformação
Antes:
Depois:
✅ Checklist
<corresp><contrib-group>🧪 Como Testar
<corresp>em<back>ou<body><author-notes>em<article-meta><article-meta>está correta📝 Notas Adicionais
<corresp>(precondição implementada)🔗 Issues Relacionadas
Adicionar referências a issues se aplicável