Skip to content

Fix XMLSyntaxError "Namespace prefix mailto for dade on a is not defined" in convert_html_to_xml step 30#160

Draft
Copilot wants to merge 3 commits intomainfrom
copilot/fix-xml-syntax-error
Draft

Fix XMLSyntaxError "Namespace prefix mailto for dade on a is not defined" in convert_html_to_xml step 30#160
Copilot wants to merge 3 commits intomainfrom
copilot/fix-xml-syntax-error

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 28, 2026

O que esse PR faz?

Corrige o XMLSyntaxError: Namespace prefix mailto for dade on a is not defined que aborta convert_html_to_xml_step_30_embed_html (e cascateia para XML Status BLOCKED no Article Proc) quando o HTML de origem traz atributos malformados com prefixo de namespace não declarado, p.ex. <a mailto:dade="...">.

A correção é aplicada em duas camadas (defesa em profundidade), priorizando a sanitização do conteúdo original antes da geração do HTML:

  • Nível de string (no fix()) — Adiciona remove_invalid_namespace_prefix_attributes(content) em scielo_classic_website/htmlbody/html_fixer.py, invocada como passo do fix(). Remove apenas o atributo malformado (preservando a tag <a> e os demais atributos), corrigindo o conteúdo original antes que wrap_html/fromstring sejam chamados. Robusto a valores de atributo contendo < — caso em que o remove_namespaces_from_content existente é enganado pelo splitter textual.
  • Nível de árvore — Adiciona remove_invalid_namespace_attributes(tree) em scielo_classic_website/htmlbody/html_fixer.py: percorre a árvore lxml e remove atributos cujo nome contém : mas o prefixo não está declarado. Invocada em load_html e get_fixed_html como rede de segurança após o parsing, cobrindo ambos os caminhos usados por HTMLContenthtml_to_nodeMainHTMLPipe.
  • Ambas preservam xml/xlink e atributos já mapeados em notação Clark ({uri}localname).
  • Acrescenta TestRemoveInvalidNamespaceAttributes e TestRemoveInvalidNamespacePrefixAttributes em tests/test_html_fixer.py (15 casos novos, incluindo o cenário em que o valor do atributo contém < ou > — casos em que a limpeza textual remove_namespaces_from_content falha).

Onde a revisão poderia começar?

scielo_classic_website/htmlbody/html_fixer.py — começar pela função remove_invalid_namespace_prefix_attributes (string-level) e sua chamada no pipeline do fix(); em seguida remove_invalid_namespace_attributes (tree-level) e suas chamadas em load_html / get_fixed_html.

Como este poderia ser testado manualmente?

from scielo_classic_website.htmlbody import html_fixer

# String-level (corrige o conteúdo original)
content = '<p>Hello <a mailto:dade="a<b" href="z">click</a> end</p>'
print(html_fixer.fix(content))
# -> '<p>Hello <a href="z">click</a> end</p>'

# Tree-level (rede de segurança após parsing)
from lxml import etree, html
tree = html.fromstring('<html><body><a mailto:dade="x" href="y">l</a></body></html>')
html_fixer.remove_invalid_namespace_attributes(tree)
xml = etree.tostring(tree, method="xml").decode()
etree.fromstring(xml)  # antes: XMLSyntaxError; agora: OK

Ou rodar pytest tests/test_html_fixer.py.

Validação ponta-a-ponta da pipeline (steps 10 → 20 → 30) confirmou que o input que reproduzia o erro original (<a mailto:dade="a<b" href="z">) agora é processado sem XMLSyntaxError.

Algum cenário de contexto que queira dar?

lxml.html.fromstring aceita mailto:dade como nome literal de atributo. Quando o <body> parseado é inserido no XML do artigo e re-serializado por EndPipe, o StartPipe do step 30 chama ET.fromstring(...) (parser XML estrito), que interpreta mailto: como prefixo de namespace inexistente e levanta XMLSyntaxError.

A limpeza textual existente (remove_namespaces_from_content) é frágil porque opera sobre tokens delimitados por </>: quando o valor do atributo contém um desses caracteres, ela falha em identificar o atributo malformado e ele chega intacto ao step 30. Por isso o conteúdo original é sanitizado primeiro pelo remove_invalid_namespace_prefix_attributes (string-level), que remove apenas o atributo problemático mantendo a tag, e o remove_invalid_namespace_attributes (tree-level) atua como uma segunda barreira após o parsing.

Screenshots

N/A.

Quais são tickets relevantes?

Issue reportada em scieloorg/scielo_migration referente à tarefa migrate_and_publish_articles com XML Status BLOCKED e traceback lxml.etree.XMLSyntaxError: Namespace prefix mailto for dade on a is not defined.

Referências

Copilot AI changed the title [WIP] Fix XMLSyntaxError during HTML to XML conversion Fix XMLSyntaxError "Namespace prefix mailto for dade on a is not defined" in convert_html_to_xml step 30 Apr 28, 2026
Copilot AI requested a review from robertatakenaka April 28, 2026 20:01

def load_html(content):
return fromstring(wrap_html(content))
tree = fromstring(wrap_html(content))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@copilot provavelmente esta solução não funciona porque o conteúdo original tem que ser corrigido antes de tentar gerar o html

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Boa observação. Adicionei remove_invalid_namespace_prefix_attributes no fix() para corrigir o conteúdo original (string) antes da geração do HTML, mantendo a limpeza no nível da árvore como rede de segurança (commit 6d9b31f).

Reproduzi o cenário que de fato falhava na pipeline (steps 10 → 20 → 30): quando o valor do atributo contém <, p.ex. <a mailto:dade="a<b" href="z">, o remove_namespaces_from_content existente é enganado pelo parser textual e o atributo malformado chega ao step 30, onde o ET.fromstring levanta o XMLSyntaxError. Com o novo passo no fix(), o conteúdo original passa a ser sanitizado antes do fromstring, e a pipeline completa o step 30 corretamente.

…HTML generation

Agent-Logs-Url: https://github.com/scieloorg/scielo_migration/sessions/3cb06e98-1827-4e85-96a2-b2ed33363233

Co-authored-by: robertatakenaka <505143+robertatakenaka@users.noreply.github.com>
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.

Migração Artigo HTML: Erro XMLSyntaxError:Convert HTML to XML - step 3 failed convert_html_to_xml_step_30_embed_html

2 participants