scieloorg / PC-Programs

SciELO PC Programs
7 stars 24 forks source link

[prodtools] A aplicação quebra ao tentar ajustar XMLs quebrados #3224

Closed robertatakenaka closed 4 years ago

robertatakenaka commented 4 years ago

Descrição do problema

O xml_utils.SuitableXML.doctype não está considerando que o XML possa estar quebrado então retorna None e levanta uma exceção ao executar xml_utils.SuitableXML.format

Passos para reproduzir o problema

  1. Execute o XPM com o arquivo em anexo python xml_package_maker.py 2523-3106-adr-60-31.xml

  2. Observe o erro apresentado

    /Users/roberta.takenaka/github.com/scieloorg/PC-Programs/src/scielo/bin
    xml
    Pack /Users/roberta.takenaka/Downloads/2523-3106-adr-60-31.xml
    Traceback (most recent call last):
    File "xml_package_maker.py", line 4, in <module>
    xpm.main()
    File "/Users/roberta.takenaka/github.com/scieloorg/PC-Programs/src/scielo/bin/xml/prodtools/xpm.py", line 122, in main
    execute(INTERATIVE, xml_list, GENERATE_PMC, sgmxml, acron)
    File "/Users/roberta.takenaka/github.com/scieloorg/PC-Programs/src/scielo/bin/xml/prodtools/xpm.py", line 31, in execute
    pkg = pkg_maker.pack(xml_list)
    File "/Users/roberta.takenaka/github.com/scieloorg/PC-Programs/src/scielo/bin/xml/prodtools/processing/sps_pkgmaker.py", line 422, in pack
    item, doc_outs, dtd_location_type, optimise_individually)
    File "/Users/roberta.takenaka/github.com/scieloorg/PC-Programs/src/scielo/bin/xml/prodtools/processing/sps_pkgmaker.py", line 311, in _enhance_doc_package
    pretty_print=True)
    File "/Users/roberta.takenaka/github.com/scieloorg/PC-Programs/src/scielo/bin/xml/prodtools/utils/xml_utils.py", line 225, in write
    dest_file_path, self.format(pretty_print, dtd_location_type))
    File "/Users/roberta.takenaka/github.com/scieloorg/PC-Programs/src/scielo/bin/xml/prodtools/utils/xml_utils.py", line 217, in format
    self.content,
    TypeError: sequence item 1: expected str instance, NoneType found

    Comportamento esperado

    Aplicação não pode quebrar após o provável ajuste do XML, nos momentos em que ela lê o XML de saída de SuitableXML.write()

Screenshots ou vídeos

n/a

Anexos

2523-3106-adr-60-31.xml.zip

Ambiente utilizado

n/a

robertatakenaka commented 4 years ago

@patymori Estou reanalisando este issue. E possivelmente o foco vai mudar.

    def format(self, pretty_print=False, dtd_location_type=None):
        doctype = self.get_doctype(dtd_location_type)
        if self.xml is not None:
            return etree.tostring(
                self.xml, encoding="utf-8", method="xml",
                xml_declaration=self.xml_declaration,
                pretty_print=pretty_print, doctype=doctype
                ).decode("utf-8")
        return "\n".join([
                self.xml_declaration,
                self.doctype,
                self.content,
            ])

Este atributo é usado somente dentro desta classe. E não faz sentido. Podemos eliminá-lo.

Ele é chamado em:

    def write(self, dest_file_path, pretty_print=True,
              dtd_location_type=None):
        doctype = self.get_doctype(dtd_location_type)
        if self.xml is None:
            fs_utils.write_file(
                dest_file_path, self.format(pretty_print, dtd_location_type))
        else:
            self.xml.write(
                dest_file_path, encoding="utf-8", method="xml",
                xml_declaration=self.xml_declaration,
                pretty_print=pretty_print, doctype=doctype)

Em seu lugar:

            fs_utils.write_file(
                dest_file_path, self.format(pretty_print, dtd_location_type))

Poderia estar simplesmente:

            fs_utils.write_file(
                dest_file_path, doctype + self.content)

O atributo dtd_location_type tem a ver se no DOCTYPE a localização é na Internet (teria http...) ou só o nome do arquivo da DTD. Isso é importantíssimo porque no site da metodologia clássica se o endereço for completo, com http, a página do artigo demorará muito a carregar. Mas no caso, como o XML está mal formado (self.xml is None), então o valor de doctype é None, pois o doctype é obtido de self.get_doctype. Se o packtools, conseguir validar sem o DOCTYPE, indicando a linha em que o XML tem erro, então tudo bem.

Outro detalhe, que inclusive é bug, é que mesmo o xml estando mal formado e se o valor de pretty_print=True, o desejável é que o XML tenha quebra de linhas para que ao passar pelos validadores a mensagem indique a linha mais precisamente onde está o erro. Se o XML está em uma única linha a mensagem de erro é inútil. O nome do parâmetro ser pretty_print não é o ideal. Deveria ser dado um novo nome para ficar mais explícito a intenção.

Estou analisando e fazendo uns testes. Acho que há mais coisas para modificar.

robertatakenaka commented 4 years ago

@patymori

Aparentemente todo o trabalho feito em SuitableXML para ajustar o XML, é perdido em algum ponto, talvez ao usar o etree.write, talvez ao usar o xml_utils.write (que é usado escrever o resultado de transformação). Não fiz maiores análises. Só vi que o XML que deveria ficar disponível em <site local>/bases/xml/<acron>/<issue>.xml, estava sem xml declartion, sem doctype, e havia entidade no lugar de caracteres acentuados.