Skip to content

process_xref() perde texto entre <xref> irmãos quando o primeiro é removido #1305

Description

@Rossi-Luciano

Descrição do problema

process_xref() (packtools/sps/utils/xml_utils.py) pode descartar texto entre dois elementos <xref> irmãos diretos quando o primeiro deles é removido (por ser ref-type="fn", marcador de pontuação como "*", ou conteúdo numérico).

O código só cria o marcador de preservação de tail (EMPTYTAGTOKEEPXREFTAIL) quando xref.getnext() não é outro <xref>:

if xref.tail:
    _next = xref.getnext()
    if _next is None or _next.tag != "xref":
        e = etree.Element("EMPTYTAGTOKEEPXREFTAIL")
        e.tail = xref.tail
        xref.tail = None
        xref.addnext(e)

O problema é que getnext() retorna o próximo elemento irmão, ignorando texto entre eles — então dois <xref> separados por texto (ex.: "1, " entre citações) ainda contam como "adjacentes" para essa condição, e o marcador não é criado. Se o primeiro <xref> for removido logo depois, seu tail (o texto entre os dois) é descartado junto.

Não é causado por nenhuma versão específica do lxml — reproduzi em 4.9.3, 5.2.1 e 6.1.1 igualmente.

Passos para reproduzir o problema

from lxml import etree
from packtools.sps.utils import xml_utils

node = etree.fromstring(
    '<p>ver notas <xref ref-type="fn">1</xref>, <xref ref-type="fn">2</xref>.</p>'
)
result = xml_utils.process_xref(node)
print(etree.tostring(result))
# b'<p>ver notas .</p>'  -- o ", " entre os dois xrefs sumiu

Comportamento esperado

O texto entre os dois <xref> (", " no exemplo) deveria ser preservado, assim como já acontece quando o próximo irmão não é um <xref>.

Anexos

Encontrado ao escrever testes de regressão para PR #1283 (bump lxml 4.9.3 → 6.1.1). Teste que documenta o comportamento atual: ProcessXrefTailPreservationTest.test_sibling_fn_xrefs_lose_intervening_text_known_bug em tests/sps/utils/test_xml_utils.py (branch chore/1251-phase4-lxml, ainda não enviada).

Ambiente utilizado

Não aplicável (bug de lógica, independente de ambiente/navegador).

Activity

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions